Bla*_*ift 14 python oop python-2.x
何时(为什么)__new__()引入了Python 函数?
创建类的实例需要三个步骤,例如MyClass():
MyClass.__call__()叫做。此方法必须在的元类中定义MyClass。MyClass.__new__()被调用__call__。MyClass自行定义。这将创建实例。MyClass.__init__()被(也称为__call__)。这将初始化实例。实例的创建会受到重载__call__或的影响__new__。通常没有理由重载__call__而不是重载__new__(例如,使用元类的__call__方法而不是__new__?)。
我们有一些旧代码(仍然运行得很强大!),其中__call__的重载位置。给出的原因是__new__当时尚不可用。因此,我尝试了解有关Python和我们的代码的历史的更多信息,但是我不知道何时__new__引入。
__new__出现在用于Python 2.4文档,而不是在那些Python 2.3中,但它不会出现在whathsnew任何Python 2中的版本。我可以找到的第一个提交__new__(将descr-branch合并回主干。)是2001年开始的,但是“ back into trunk”消息表明以前有过。几个月前的PEP 252(使类型看起来更像类)和PEP 253(对内置类型进行子类型化)似乎很重要。
学习更多有关引入的知识__new__将使我们更多地了解Python为何如此。
编辑以澄清:
似乎class.__new__重复了所提供的功能metaclass.__call__。添加仅以更好的方式复制现有功能的方法似乎不符合Pythonic。
__new__是您可以直接使用的少数几个类方法之一(cls例如,第一个参数),从而引入了以前没有的复杂性。如果类是函数的第一个参数,则可以认为该函数应该是元类的常规方法。但是该方法已经存在:__call__()。我觉得我想念什么。
应该有一种-最好只有一种-显而易见的方法。
(Python的BDFL)撰写的博客文章The Inside Story on New-Style Classes
(以恰当的名称命名)提供了有关此主题的一些良好信息。http://python-history.blogspot.comGuido van Rossum
一些相关的报价:
新型类引入了新的类方法
__new__(),该方法使类作者可以自定义创建新类实例的方式。通过重写__new__(),类作者可以实现诸如Singleton Pattern之类的模式,返回先前创建的实例(例如,从自由列表中返回),或者返回不同类的实例(例如,子类)。但是,使用__new__具有其他重要的应用程序。例如,在pickle模块中,__new__用于反序列化对象时创建实例。在这种情况下,将创建实例,但__init__不会调用该方法。的另一种用法
__new__是帮助实现不可变类型的子类化。由于其不可变性的性质,无法通过标准__init__()方法初始化这些类型的对象。相反,在创建对象时必须执行任何特殊的初始化。例如,如果类想要修改存储在不可变对象中的值,则该__new__方法可以通过将修改后的值传递给基类__new__方法来实现。
您可以阅读全文,以获取有关此主题的更多信息。
New-style Classes与上面引用的文章一起撰写的另一篇文章还包含一些其他信息。
编辑:
为了回应OP的编辑以及Python Zen的引用,我会这样说。
Python的Zen不是由该语言的创建者编写的,而是由Tim Peters编写的,仅在2004年8月19日发布。我们必须考虑到__new__仅出现在Python 2.4文档中的事实(该文档于11月30日发布),2004年),而该特定准则(或格言)在引入该语言时甚至没有公开存在__new__。
即使这样的指导性文件以前是非正式存在的,我也不认为作者希望将它们误解为整个语言和生态系统的设计文件。
我不会在这里解释它的历史__new__,因为我从 2005 年开始才使用 Python,所以在它被引入到该语言之后。但这背后的理由如下。
新对象的正常配置方法是其类的方法。__init__该对象已经被创建(通常通过间接调用object.__new__)并且该方法只是初始化它。简而言之,如果您有一个真正不可变的对象,那就太晚了。
在该用例中,Pythonic 方式是__new__方法,它构建并返回新对象。它的优点是它仍然包含在类定义中并且不需要特定的元类。标准文件规定:
new () 主要旨在允许不可变类型(如 int、str 或 tuple)的子类自定义实例创建。它通常在自定义元类中被重写,以便自定义类创建。
__call__在元类上定义方法确实是允许的,但恕我直言,它不是 Pythonic,因为__new__应该足够了。此外,__init__、__new__和元类都更深入地挖掘内部 Python 机制。所以规则应该是不要使用__new__if __init__is enough ,并且不要使用元类 if __new__is enough。
| 归档时间: |
|
| 查看次数: |
803 次 |
| 最近记录: |