在元类中重写super().__new__()
时调用__new__
包含以下函数签名:
class MyMeta(type):
def __new__(cls, name, bases, classdict):
clsobj = super().__new__(cls, name, bases, classdict)
但是,当在常规类中覆盖__new__
时,我们具有以下内容:
class A:
def __new__(cls, *a, **kw):
clsobj = super().__new__(cls)
将任何其他参数传递给super()
中的A.__new__
会导致以下错误:
TypeError: object.__new__() takes exactly one argument (the type to instantiate)
我了解在第二种情况下,我们正在处理object.__new__
,而在第一种情况下,我们正在处理type.__new__
。
我的问题是,为什么这些功能签名不同?为什么object.__new__
只接受cls
?
object
和type
有一个有趣的关系。 object
是type
的实例,但是type
是object
的子类。
__new__
专注于创建类的实例,因此object.__new__
是最低的公分母:它实际上不执行任何操作,因为实例几乎不执行任何操作每个 可能的类的共同点。因此,object.__new__
所需要的信息与其返回值的类型无关。
type.__new__
的功能远远超过object.__new__
:它必须创建一个本身能够创建新对象的对象。这需要更多的信息,因此type.__new__
在覆盖object.__new__
时定义了几个附加参数。
但是请注意,type
本身不使用super
;如果定义两个类
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__
是行的结尾。
但是,通常,您不会混合这样的类。就像您很少在类的基类列表中包含object
(我几乎愿意说您永远一样)一样,您通常不会从{{1} }和另一个(元)类,我想不出任何理由尝试同时继承type
和type
的非类型子类。