python - 什么时候(以及为什么)引入 Python `__new__()`?

标签 python oop python-2.x

何时(以及为什么)引入 Python __new__() 函数?

创建一个类的实例分为三个步骤,例如MyClass():

  • MyClass.__call__() 被调用。此方法必须在 MyClass 的元类中定义。
  • MyClass.__new__() 被调用(通过 __call__)。在 MyClass 本身上定义。这将创建实例。
  • MyClass.__init__() 被调用(也由 __call__)。这将初始化实例。

实例的创建会受到重载 __call____new__ 的影响。通常没有理由重载 __call__ 而不是 __new__ (例如 Using the __call__ method of a metaclass instead of __new__? )。

我们有一些旧代码(仍然运行良好!),其中 __call__ 过载。给出的原因是 __new__ 当时不可用。所以我试图了解更多关于 Python 和我们的代码的历史,但我无法弄清楚 __new__ 是什么时候引入的。

__new__ 出现在 documentation for Python 2.4 中而不是那些 Python 2.3 , 但它没有出现在 whathsnew 中任何 Python 2 版本。 first commit that introduced __new__ (将 descr-branch 合并回主干。)我能找到的是从 2001 年开始的,但是“回到主干”消息表明之前有一些东西。 PEP 252 (Making Types Look More Like Classes)PEP 253 (Subtyping Built-in Types)从几个月前开始似乎是相关的。

了解更多关于 __new__ 的介绍会让我们更多地了解为什么 Python 是现在这样。


编辑澄清:

似乎 class.__new__ 复制了 metaclass.__call__ 已经提供的功能。添加一个方法只是为了以更好的方式复制现有功能似乎是非 Pythonic 的。

__new__ 是少数几个开箱即用的类方法之一(即使用 cls 作为第一个参数),从而引入了以前没有的复杂性.如果类是函数的第一个参数,那么可以说函数应该是元类的普通方法。但该方法确实已经存在:__call__()。我觉得我错过了什么。

There should be one-- and preferably only one --obvious way to do it.

最佳答案

博文The Inside Story on New-Style Classes (来自恰当命名的 http://python-history.blogspot.com)由 Guido van Rossum 编写(Python 的 BDFL)提供了一些有关此主题的有用信息。

一些相关的引述:

New-style classes introduced a new class method __new__() that lets the class author customize how new class instances are created. By overriding __new__() a class author can implement patterns like the Singleton Pattern, return a previously created instance (e.g., from a free list), or to return an instance of a different class (e.g., a subclass). However, the use of __new__ has other important applications. For example, in the pickle module, __new__ is used to create instances when unserializing objects. In this case, instances are created, but the __init__ method is not invoked.

Another use of __new__ is to help with the subclassing of immutable types. By the nature of their immutability, these kinds of objects can not be initialized through a standard __init__() method. Instead, any kind of special initialization must be performed as the object is created; for instance, if the class wanted to modify the value being stored in the immutable object, the __new__ method can do this by passing the modified value to the base class __new__ method.

您可以阅读整篇文章以获取有关此主题的更多信息。

另一篇关于 New-style Classes 的帖子与上面引用的帖子一起写的有一些额外的信息。

编辑:

为了回应OP的编辑和Python之禅的引述,我会这样说。
Zen of Python不是该语言的创建者而是由 Tim Peters 编写的,并且仅在 2004 年 8 月 19 日发布。我们必须考虑到 __new__ 仅出现在 Python 2.4 的文档中(在 November 30, 2004 上发布),当 __new__ 被引入语言时,这个特定的指南(或格言)甚至不存在公开

即使这样的指南文档以前非正式存在,我也不认为作者有意将它们误解为整个语言和生态系统的设计文档。

关于python - 什么时候(以及为什么)引入 Python `__new__()`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55966757/

相关文章:

python - url_for 创建了错误的静态文件夹路径

c++ - 在相同状态类型的各种屏幕之间切换?

python-3.x - python2 和 3 之间对于带前导零的数字的区别。

python - Python 中的换行符从哪里来?

java - 从文件中获取数据到对象数组中(java)

python - 在 ConfigParser 中保留大小写?

python - 如何使用递归判断字符串中是否包含字符?

python - 'time' 对象的描述符 'datetime.datetime' 需要参数

python - keras 使用激活层而不是激活参数

java对象间通信