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

objecttype 有一个有趣的关系。 objecttype 的实例,但 typeobject 的子 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.