在现代Python中扩展父类方法的正确方法是什么

Gor*_*ley 21 python inheritance

我经常这样做:

class Person(object):
    def greet(self):
        print "Hello"

class Waiter(Person):
    def greet(self):
        Person.greet(self)
        print "Would you like fries with that?"
Run Code Online (Sandbox Code Playgroud)

Person.greet(self)这行似乎不对.如果我改变了Waiter继承的类,我将不得不追踪其中的每一个并将它们全部替换掉​​.

现代Python的正确方法是什么?2.x和3.x都有,我知道这个区域有3个变化.

如果重要的是我通常坚持单继承,但如果需要额外的东西来正确地适应多重继承,那么了解它就是好的.

Kat*_*iel 20

你用super:

返回将方法调用委托给父类或兄弟类类型的代理对象.这对于访问已在类中重写的继承方法很有用.getattr()除了跳过类型本身之外,搜索顺序与使用的搜索顺序相同 .

换句话说,一个调用super返回一个伪对象,该对象将属性查找委托给继承链中的上面的类.注意事项:

  • 这不适用于旧式类 - 因此,如果您使用的是Python 2.x,则需要确保层次结构中的顶级类继承自object.
  • 您需要将自己的类和实例传递给superPython 2.x. 该要求在3.x中被免除.
  • 这将正确处理所有多重继承.(如果在Python中有多重继承树,则会生成方法解析顺序,并且查找按此顺序通过父类.)

小心:有很多地方对Python中的多重继承感到困惑.您可能想阅读super()Considered Harmful.如果您确定要坚持使用单个继承树,并且不打算更改所述树中类的名称,则可以像上面那样对类名进行硬编码,一切都会正常工作.

  • 这是 [super()](http://docs.python.org/py3k/library/functions.html#super) 3.x 版本的文档链接。 (2认同)

Óla*_*age 9

不确定你是否正在寻找这个,但你可以通过这样做来打电话给父母而不参考它.

super(Waiter, self).greet()
Run Code Online (Sandbox Code Playgroud)

这将调用该greet()函数Person.

  • 只是为了记录,你也可以使用`super(self .__ class__,self).greet()`.这样,如果你改变了Waiter的名字,你不必重写你的超级. (2认同)

Ben*_*Ben 5

katrielalex 的回答确实是您问题的答案,但这不适合发表评论。

如果您打算super到处使用,并且您曾经考虑过多重继承,请务必阅读“super() 被认为有害”链接。super()是一个很好的工具,但需要理解才能正确使用。根据我的经验,对于看起来不太可能陷入复杂的菱形继承缠结的简单事物,直接调用超类并在更改基类的名称时处理重命名实际上更容易也更乏味。

实际上,在 Python2 中,您必须包含当前类名,这通常比基类名更容易更改。(事实上​​,如果你在做一些古怪的事情,有时很难传递对当前类的引用;在定义方法时,类没有绑定到任何名称,并且在super调用时执行时,类的原始名称可能不会仍然绑定到类,例如当您使用类装饰器时)