Python 3 中默认的 ```__new__``` 是什么?
What's ```__new__``` by default in Python 3?
我相信我对 __new__
应该做什么有某种理解(创建一个 class 的实例,但不初始化它,这是 [=13 的工作=]).但是,我想了解 Python 3 默认情况下作为 __new__
方法实现的内容。
我还发现 cls
是 __new__
的参数,但 __new__
是静态方法而不是 class 方法(我从documentation)... 现在如何将类型作为第一个参数传递给它?
根据我的理解,__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
Typical implementations create a new instance of the class by invoking the superclass’s __new__()
method using super().new(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it.
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__()
不是 return 实例,因此输出的值为 NoneType
希望这能回答您的问题
第一部分:__new__
默认做什么?因为从头开始创建对象是一项基本的、特定于实现的操作,所以 object.__new__
的定义(与 object
的其余定义一样)必然是实现本身的一部分。这意味着您需要查看 CPython、PyPy、Cython 等的源代码,以准确了解在 Python 的任何特定实现中如何管理对象创建。通常,这些都是无法直接从 Python 本身访问的低级簿记。
第二部分:__new__
如何知道它得到了一个class参数?因为它 假定 它的第一个参数是 class,如果调用者希望 __new__
正常工作,最好提供一个 class!也就是说,没有人真正明确地调用 __new__
,除非通过 super
覆盖 __new__
,然后,您必须确保自己明确传递 cls
:
def __new__(cls, *args, **kwargs):
rv = super().__new__(cls, *args, **kwargs) # Not super().__new__(*args, **kwargs)
其余时间,您创建 class Foo
的实例不是通过直接调用 Foo.__new__(Foo, ...)
,而是通过调用类型本身:Foo(...)
. 这 得到管理是因为Foo
的元class 的__call__
方法负责为您调用__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
请注意,仅当 __new__
实际上 returns 是 class 调用 __new__
的实例时才会调用 __init__
。
我相信我对 __new__
应该做什么有某种理解(创建一个 class 的实例,但不初始化它,这是 [=13 的工作=]).但是,我想了解 Python 3 默认情况下作为 __new__
方法实现的内容。
我还发现 cls
是 __new__
的参数,但 __new__
是静态方法而不是 class 方法(我从documentation)... 现在如何将类型作为第一个参数传递给它?
根据我的理解,__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
Typical implementations create a new instance of the class by invoking the superclass’s
__new__()
method using super().new(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it.
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__()
不是 return 实例,因此输出的值为 NoneType
希望这能回答您的问题
第一部分:__new__
默认做什么?因为从头开始创建对象是一项基本的、特定于实现的操作,所以 object.__new__
的定义(与 object
的其余定义一样)必然是实现本身的一部分。这意味着您需要查看 CPython、PyPy、Cython 等的源代码,以准确了解在 Python 的任何特定实现中如何管理对象创建。通常,这些都是无法直接从 Python 本身访问的低级簿记。
第二部分:__new__
如何知道它得到了一个class参数?因为它 假定 它的第一个参数是 class,如果调用者希望 __new__
正常工作,最好提供一个 class!也就是说,没有人真正明确地调用 __new__
,除非通过 super
覆盖 __new__
,然后,您必须确保自己明确传递 cls
:
def __new__(cls, *args, **kwargs):
rv = super().__new__(cls, *args, **kwargs) # Not super().__new__(*args, **kwargs)
其余时间,您创建 class Foo
的实例不是通过直接调用 Foo.__new__(Foo, ...)
,而是通过调用类型本身:Foo(...)
. 这 得到管理是因为Foo
的元class 的__call__
方法负责为您调用__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
请注意,仅当 __new__
实际上 returns 是 class 调用 __new__
的实例时才会调用 __init__
。