Python `__new__()` 是什么时候(以及为什么)引入的?

When (and why) was Python `__new__()` introduced?

何时(以及为什么)引入 Python __new__() 功能?

创建 class 的实例需要三个步骤,例如MyClass():

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

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

__new__ 出现在 documentation for Python 2.4 and not in those for Python 2.3, but it does not appear in the whathsnew of any of the Python 2 versions. The first commit that introduced __new__ (Merge of descr-branch back into trunk.) that I could find is from 2001, but the 'back into trunk' message is an indication that there was something before. PEP 252 (Making Types Look More Like Classes) and PEP 253 (Subtyping Built-in Types) 从几个月前似乎是相关的。

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


编辑澄清:

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

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

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

这里就不解释__new__的历史了,因为我从2005年才开始使用Python,所以在它被引入语言之后。但这是其背后的基本原理。

新对象的正常配置方法是其class的__init__方法。该对象已经被创建(通常通过间接调用 object.__new__)并且该方法只是 初始化 它。简单地说,如果你有一个真正的非可变对象,那就太晚了。

在那个用例中,Pythonic 方法是 __new__ 方法,它构建并 returns 新对象。它的优点在于它仍然包含在 class 定义中并且不需要特定的元 class。标准文档状态:

new() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.

确实允许在 metaclass 上定义 __call__ 方法,但恕我直言,它不是 Pythonic,因为 __new__ 应该足够了。此外,__init____new__ 和 metaclasses 都深入挖掘了内部 Python 机制。所以规则应该是 如果 __init__ 足够就不要使用 __new__,如果 __new__ 足够就不要使用 metaclasses.

博客postThe 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.

您可以阅读整个 post 以获取有关此主题的更多信息。

关于 New-style Classes 的另一个 post 是与上面引用的 post 一起写的,有一些额外的信息。

编辑:

为了回应 OP 的编辑和 Python 的 Zen 引用,我会这样说。
Zen of Python was not written by the creator of the language but by Tim Peters and was published only in August 19, 2004. We have to take into account the fact that __new__ appears only in the documentation of Python 2.4 (which was released on November 30, 2004),当 __new__ 被引入该语言时,这个特定的准则(或格言)甚至 公开 不存在。

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