super 和 __new__ 的困惑

27 投票
1 回答
8805 浏览
提问于 2025-04-17 02:35

根据我刚学到的,我可以这样使用 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,而不需要指定 objcls 来操作。但是,为什么在 __new__ 的情况下我不能这样做呢?因为在情况3中,如果我那样使用 super,就会出现错误。但是如果我这样使用:

super(B, cls).__new__(cls)

就没有错误了。

1 个回答

34

在关于重写 __new__ 方法的 Python 发布说明 中提到:

__new__ 是一个静态方法,而不是类方法。一开始我以为它必须是类方法,所以我加了一个类方法的标记。但不幸的是,在这种情况下,类方法的调用不太对劲,所以我不得不把它做成一个静态方法,并且第一个参数要明确指定类

因为 __new__ 是静态方法,所以 super(...).__new__ 返回的也是一个静态方法。在这种情况下,cls 并不会自动绑定到第一个参数上。所有的参数都需要明确提供。

撰写回答