我相信我对__new__
应该做的事情有某种理解(创建类的实例,但不初始化它,这是__init__
的工作)。不过,我想了解Python 3默认情况下是作为__new__
方法实现的。
我还发现cls
是__new__
的参数有点令人困惑,但是__new__
是静态方法而不是类方法(我从documentation获得了此方法) ...现在如何将类型作为其第一个参数传递给它?
答案 0 :(得分:2)
第一部分:__new__
的默认设置是什么?因为从头开始创建对象是一项基本的,特定于实现的操作,所以object.__new__
的定义必定是实现本身的一部分(就像object
的其余部分一样)。这意味着您需要查看CPython,PyPy,Cython等的源代码,以确切了解如何在任何特定的Python实现中管理对象创建。通常,所有这些低级别的簿记都是无法直接从Python本身直接访问的。
第二部分:__new__
如何知道它得到一个类参数?因为它假定的第一个参数是一个类,并且调用者最好期望__new__
正常工作,所以最好提供一个类!就是说,除了通过__new__
的覆盖中的super
之外,没有人真正真正地__new__
调用过,然后,您必须确保自己明确地传递cls
:< / p>
def __new__(cls, *args, **kwargs):
rv = super().__new__(cls, *args, **kwargs) # Not super().__new__(*args, **kwargs)
其余时间,您不是通过直接调用Foo
而是仅通过调用类型本身Foo.__new__(Foo, ...)
来创建类Foo(...)
的实例。 对此进行管理是因为__call__
的元类的Foo
方法可以为您调用__new__
。例如,您可以想象type.__call__
被大致定义为
# A regular instance method of type; we use cls instead of self to
# emphasize that an instance of a metaclass is a class
def __call__(cls, *args, **kwargs):
rv = cls.__new__(cls, *args, **kwargs) # Because __new__ is static!
if isinstance(rv, cls):
rv.__init__(*args, **kwargs)
return rv
请注意,只有在__init__
实际上首先返回调用__new__
的类的实例时,才会调用__new__
。
答案 1 :(得分:0)
根据我的理解,__new__()
的默认实现是这样的
class Default(object):
def __new__(cls, *args, **kwargs):
print("In new")
return super().__new__(cls,*args, **kwargs)
def __init__(self):
print("In init default")
default = Default()
print(type(default))
输出
In new
In init default
<class '__main__.Default'>
基于文档 https://docs.python.org/3/reference/datamodel.html#object.new
典型的实现通过使用super()调用超类的
__new__()
方法来创建该类的新实例。 new (cls [,...])和适当的参数,然后进行修改返回之前,根据需要创建新实例。
super().__new__()
调用将创建实例,__init__()
将初始化。
下面的代码显示__new__()
的错误覆盖
class InccorectOverride(object):
def __new__(cls, *args, **kwargs):
pass
def __init__(self):
print("In init InccorectOverride")
a = InccorectOverride()
print(type(a))
输出
<class 'NoneType'>
由于__new__()
不返回实例,因此输出的值为NoneType
希望这能回答您的问题