super().__new__() for object vs type in Python 3.7
super().__new__() for object vs type in Python 3.7
在元 class 中覆盖 __new__
时调用 super().__new__()
包含以下函数签名:
class MyMeta(type):
def __new__(cls, name, bases, classdict):
clsobj = super().__new__(cls, name, bases, classdict)
然而,当在正常 class 中覆盖 __new__
时,我们有以下内容:
class A:
def __new__(cls, *a, **kw):
clsobj = super().__new__(cls)
在 A.__new__
中将任何其他参数传递给 super()
将导致以下错误:
TypeError: object.__new__() takes exactly one argument (the type to instantiate)
我了解到,在第二种情况下,我们正在处理 object.__new__
,而在第一种情况下,我们正在处理 type.__new__
。
我的问题是,为什么这些函数签名不同?为什么object.__new__
只接受cls
?
object
和 type
有一个有趣的关系。 object
是 type
的实例,但 type
是 object
的子 class。
然而,__new__
侧重于创建 class 的实例,因此 object.__new__
是最小公分母:它本身几乎什么都不做,因为every possible class 的实例几乎没有任何共同点。因此,object.__new__
不需要比其 return 值将具有的类型更多的信息。
type.__new__
比 object.__new__
做的多很多:它必须创建一个本身能够创建新对象的对象。这需要更多信息,因此 type.__new__
在覆盖 object.__new__
.
时定义了几个附加参数
但是请注意,type
本身 而不是 使用 super
;如果你定义两个 classes
class A:
def __new__(cls, *args, **kwargs):
print("In A.__new__")
return super().__new__(cls)
class B(type, A):
def __new__(cls, name, bases, dct, *args, **kwargs):
print("In B.__new__")
return super().__new__(cls, name, bases, dct)
您会看到 B("B", (), {})
输出 In B.__new__
而不是 In A.__new__
。 type.__new__
是行尾,可以这么说,用于创建元classes。
不过,通常情况下,您不会像这样混合使用 class。就像你很少在 class 的基础 class 列表中包含 object
一样(我几乎愿意说你 永远不会 会) ,你不经常从 type
和另一个 (meta)class 继承,我想不出你为什么会尝试从 type
和非 -输入 subclass of object
.
在元 class 中覆盖 __new__
时调用 super().__new__()
包含以下函数签名:
class MyMeta(type):
def __new__(cls, name, bases, classdict):
clsobj = super().__new__(cls, name, bases, classdict)
然而,当在正常 class 中覆盖 __new__
时,我们有以下内容:
class A:
def __new__(cls, *a, **kw):
clsobj = super().__new__(cls)
在 A.__new__
中将任何其他参数传递给 super()
将导致以下错误:
TypeError: object.__new__() takes exactly one argument (the type to instantiate)
我了解到,在第二种情况下,我们正在处理 object.__new__
,而在第一种情况下,我们正在处理 type.__new__
。
我的问题是,为什么这些函数签名不同?为什么object.__new__
只接受cls
?
object
和 type
有一个有趣的关系。 object
是 type
的实例,但 type
是 object
的子 class。
__new__
侧重于创建 class 的实例,因此 object.__new__
是最小公分母:它本身几乎什么都不做,因为every possible class 的实例几乎没有任何共同点。因此,object.__new__
不需要比其 return 值将具有的类型更多的信息。
type.__new__
比 object.__new__
做的多很多:它必须创建一个本身能够创建新对象的对象。这需要更多信息,因此 type.__new__
在覆盖 object.__new__
.
但是请注意,type
本身 而不是 使用 super
;如果你定义两个 classes
class A:
def __new__(cls, *args, **kwargs):
print("In A.__new__")
return super().__new__(cls)
class B(type, A):
def __new__(cls, name, bases, dct, *args, **kwargs):
print("In B.__new__")
return super().__new__(cls, name, bases, dct)
您会看到 B("B", (), {})
输出 In B.__new__
而不是 In A.__new__
。 type.__new__
是行尾,可以这么说,用于创建元classes。
不过,通常情况下,您不会像这样混合使用 class。就像你很少在 class 的基础 class 列表中包含 object
一样(我几乎愿意说你 永远不会 会) ,你不经常从 type
和另一个 (meta)class 继承,我想不出你为什么会尝试从 type
和非 -输入 subclass of object
.