为什么__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__
]
超().__新__()调用传递MCL明确,虽然。我不懂 为什么。签名看起来和我一样。
__new__
方法是一个奇怪的地方,它是一个静态方法,但它是特殊的,所以你不必声明它是这样的。作为一个静态方法意味着你必须显式地传入任何需要的变量(在这种情况下,元类)。
相比之下,__init__
就像其他常规方法一样。从实例中查找时,实例会自动作为第一个参数传入。无论您直接拨打cls.__init__(name, bases, nmspc)
还是使用super()和super(MetaBase, cls).__init__(name, bases, nmspc)
,都可以使用此功能。作为第一个参数,他们都通过cls。这就是绑定方法对于普通类和元类的工作方式。不管是否使用super()。
所以,一个奇怪的情况是__new__
,因为它是一个staticmethod,它根据定义没有自动预先计划行为。
我应该期望在重写其他魔术 方法时被此咬?
静态方法很少见。在神奇的方法中,__new__
是我能想到的唯一。所以,你应该安全:-)
'__new__'是一种静态方法。 '__init__'是一个实例方法。 – spectras
[Python使用\ _ \ _ new \ _ \ _和\ _ \ _ init \ _ \ _?]的可能重复(http://stackoverflow.com/questions/674304/pythons-use-of-new-and- init) – spectras
关于编辑,'__new__'官方文档的第一句话:“[__new __()是一个静态方法(特殊的,所以你不需要声明它)](https://docs.python.org/3 /参考/数据模型。html#object .__ new__)“ – spectras