super 和 __new__ 的困惑
根据我刚学到的,我可以这样使用 super()
:
super(类名, 类的实例或子类的实例)
下面是代码:
#Case 1
class A(object):
def __init__(self):
print "A init"
class B(A):
def __init__(self):
print "B init"
super(B, self).__init__() #ok, I can invoke A's __init__ successfully
#Case 2
class A(object):
@classmethod
def foo(cls):
print "A foo"
class B(object):
@classmethod
def foo(cls):
print "B foo"
super(B, cls).foo() #ok, I can invoke A's foo successfully
#Case 3
class A(object):
def __new__(cls):
print "A new"
return super(A, cls).__new__(cls)
class B(A):
def __new__(cls):
print "B new"
return super(B, cls).__new__() #Oops, error
问题:
在情况1和2中,我可以成功使用 super,而不需要指定 obj
或 cls
来操作。但是,为什么在 __new__
的情况下我不能这样做呢?因为在情况3中,如果我那样使用 super,就会出现错误。但是如果我这样使用:
super(B, cls).__new__(cls)
就没有错误了。
1 个回答
34
在关于重写 __new__
方法的 Python 发布说明 中提到:
__new__
是一个静态方法,而不是类方法。一开始我以为它必须是类方法,所以我加了一个类方法的标记。但不幸的是,在这种情况下,类方法的调用不太对劲,所以我不得不把它做成一个静态方法,并且第一个参数要明确指定类。
因为 __new__
是静态方法,所以 super(...).__new__
返回的也是一个静态方法。在这种情况下,cls
并不会自动绑定到第一个参数上。所有的参数都需要明确提供。