如果你已经习惯于通过直接调用父类并传入 self 作为第一个参数来访问类的属性或 方法,那么 super 的用法会有些令人困惑。这是非常陈旧的模式,但仍然可以在一些代码 库中找到(特别是遗留项目)。参见以下代码:

class Mama: # 旧的写法 def says(self):

               print('do your homework')

       class Sister(Mama):

           def says(self):

               Mama.says(self)

               print('and clean your bedroom')

  在解释器会话中运行,它会给出如下结果:

    >>> Sister().says()

    do your homework

    and clean your bedroom

重点看一下 Mama.says(self)这一行,这里我们使用刚刚提到的方法来调用超类 (即 Mama 类)的 says()方法,并将 self 作为参数传入。也就是说,调用的是属于 Mama

的 says()方法。但它的作用对象由 self 参数给出,在这个例子中是一个 Sister 实例。 而 super 的用法如下所示:

       class Sister(Mama):

           def says(self):

               super(Sister, self).says()

print('and clean your bedroom') 或者,你也可以使用 super()调用的简化形式如下:

       class Sister(Mama):

           def says(self):

               super().says()

               print('and clean your bedroom')

super 的简化形式(不传入任何参数)可以在方法内部使用,但 super 的使用并不 限于方法。在代码中需要调用给定实例的超类方法的任何地方都可以使用它。不过,如果 super 不在方法内部使用,那么必须给出如下参数:

>>> anita = Sister()

>>> super(anita.__class__, anita).says() do your homework

最后,关于 super 还有很重要的一点需要注意,就是它的第二个参数是可选的。如果 只提供了第一个参数,那么 super 返回的是一个未绑定(unbound)类型。这一点在与 classmethod 一起使用时特别有用,如下所示:

class Pizza:

def __init__(self, toppings):

              self.toppings = toppings

def __repr__(self):

return "Pizza with " + " and ".join(self.toppings)

          @classmethod

          def recommend(cls):

"""推荐任意馅料(toppings)的某种披萨。""" return cls(['spam', 'ham', 'eggs'])

      class VikingPizza(Pizza):

          @classmethod

def recommend(cls):

"""推荐与 super 相同的内容,但多加了午餐肉(spam)。""" recommended = super(VikingPizza).recommend() recommended.toppings += ['spam'] * 5

return recommended

注意,零参数的 super()形式也可用于被 classmethod 装饰器装饰的方法。在这样 的方法中无参数调用的 super()被看作是仅定义了第一个参数。

前面提到的使用实例很容易理解,但如果面对多重继承模式,super 将变得难以使用。 在解释这些问题之前,理解何时应避免使用super以及方法解析顺序(Method Resolution Order,MRO)在 Python 中的工作原理是很重要的。