super(self)的快捷方式

12 投票
1 回答
4786 浏览
提问于 2025-04-16 11:08

我在子类中重写方法时,常常会这样做:

def method_x(self):
    x = super(type(self), self).method_x()

    [Some extra code]
    return x

我想问的是:有没有更简单的方法来代替 super(type(self), self) 这个写法?

1 个回答

21

别这么做:如果 super 只需要用 type(self) 作为第一个参数,那它一开始就不会设计成需要两个参数了。这里你必须传入实际的类,而不是一个可能会因为子类化而改变的表达式。

传给 super 的第一个参数需要是包含当前方法定义的类,因为你是在告诉 super 从基类列表的哪个位置开始查找。

Python 3 知道这一点,并在编译时神奇地处理 super(),但在 Python 2.x 中,它只是一个普通的函数,所以它无法自己搞清楚这些参数。

[编辑以补充我的初始观点] 实际上,在 Python 2.x 中还有一种不太常用的方式来使用 super()。你可以使用未绑定的 super,然后在访问时将其绑定:

>>> class A(object):
    def foo(self):
        print "A.foo"


>>> class B(A):
    def foo(self):
        self.__super.foo()
        print "B.foo"


>>> B._B__super = super(B)
>>> class C(A):
    def foo(self):
        self.__super.foo()
        print "C.foo"


>>> C._C__super = super(C)
>>> class D(C,B): pass

>>> D._D__super = super(D)
>>> D().foo()
A.foo
B.foo
C.foo

这里有一个重要的注意事项:你必须使用不同的名称来存储每个 super 对象,你可以通过使用 self.__super 来做到这一点,但你不能在类定义中直接创建未绑定的 super(因为如果类还不存在,你无法命名它),而且如果你在外部创建它,你必须手动混淆名称,以确保为类设置正确的 __super 对象。对于 Python 2.6 及以后的版本,你可以考虑将其封装为一个类装饰器。

撰写回答