为什么__new__和__init__在向超类踢球时表现出不同的表现?

问题描述:

我碰到下面的代码来一边念叨元类here,虽然我不知道这种区别是特定于元类,我怀疑这是不是:为什么__new__和__init__在向超类踢球时表现出不同的表现?

class MetaBase(type): 
    def __new__(mcl, name, bases, nmspc): 
     print('MetaBase.__new__\n') 
     return super(MetaBase, mcl).__new__(mcl, name, bases, nmspc) 

    def __init__(cls, name, bases, nmspc): 
     print('MetaBase.__init__\n') 
     super(MetaBase, cls).__init__(name, bases, nmspc) 

注意,super().__init__()呼叫省略第一论据。我猜它是隐式传递的,因为它正在调用一个由super()返回的任何类的方法。这就是我通常看到的构建这样的调用的方式,虽然它们通常涉及到一个普通类上的self而不是元类上的cls/mcl。

尽管如此,super().__new__()调用通过mcl明确。我不明白为什么。签名看起来和我一样。

我很困惑。在每种情况下,super()是否会返回不同的东西?这里发生了什么事情,并且我应该在重写其他魔术方法时期望被这个问题咬伤?

[编辑:有人建议这是this question的重复,它描述了它们的不同功能。而同样差异中的一些例子显示出在那里,我看到或没有说明为什么它的存在无论是独特的__new__]

+4

'__new__'是一种静态方法。 '__init__'是一个实例方法。 – spectras

+4

[Python使用\ _ \ _ new \ _ \ _和\ _ \ _ init \ _ \ _?]的可能重复(http://*.com/questions/674304/pythons-use-of-new-and- init) – spectras

+0

关于编辑,'__new__'官方文档的第一句话:“[__new __()是一个静态方法(特殊的,所以你不需要声明它)](https://docs.python.org/3 /参考/数据模型。html#object .__ new__)“ – spectras

超().__新__()调用传递MCL明确,虽然。我不懂 为什么。签名看起来和我一样。

__new__方法是一个奇怪的地方,它是一个静态方法,但它是特殊的,所以你不必声明它是这样的。作为一个静态方法意味着你必须显式地传入任何需要的变量(在这种情况下,元类)。

相比之下,__init__就像其他常规方法一样。从实例中查找时,实例会自动作为第一个参数传入。无论您直接拨打cls.__init__(name, bases, nmspc)还是使用super()super(MetaBase, cls).__init__(name, bases, nmspc),都可以使用此功能。作为第一个参数,他们都通过cls。这就是绑定方法对于普通类和元类的工作方式。不管是否使用super()

所以,一个奇怪的情况是__new__,因为它是一个staticmethod,它根据定义没有自动预先计划行为。

我应该期望在重写其他魔术 方法时被此咬?

静态方法很少见。在神奇的方法中,__new__是我能想到的唯一。所以,你应该安全:-)