如何从基类方法调用重写方法?

wow*_*yoo 23 python inheritance class python-3.x

根据继承文件:

派生类可以覆盖其基类的方法.因为方法在调用同一对象的其他方法时没有特殊权限,所以调用同一基类中定义的另一个方法的基类方法最终可能会调用覆盖它的派生类的方法.

这是怎么发生的?有人能用一个简单的例子来说明这个概念吗?

Ian*_*ney 29

这是您请求的示例.这打印chocolate.

class Base:
    def foo(self):
        print("foo")
    def bar(self):
        self.foo()

class Derived(Base):
    def foo(self):
        print("chocolate")

d = Derived()
d.bar()  # prints "chocolate"
Run Code Online (Sandbox Code Playgroud)

chocolate打印字符串而不是foo因为Derived覆盖foo()函数.即使bar()已定义Base,它最终会调用Derived实现foo()而不是Base实现.

  • @innisfree`d`也是"Base"的一个例子,可能是混乱源于此.但是,是的,`Base().bar()`不会调用任何覆盖的方法 (3认同)

Jim*_*ard 15

它是如何工作的?

当在该类的一个实例中执行的一个属性的查找,类字典它的基类的词典中搜索以特定的顺序(参见:方法解析顺序)的适当的方法.首先发现的是被召唤.

使用以下Spam示例:

class Spam:
    def produce_spam(self):
        print("spam")
    def get_spam(self):
        self.produce_spam()

class SuperSpam(Spam):
    def produce_spam(self):
        print("super spam")
Run Code Online (Sandbox Code Playgroud)

Spam定义函数produce_spamget_spam.它们存在于Spam.__dict__(类命名空间)中.子类SuperSpam通过继承可以访问这两种方法.SuperSpam.produce_spam如果没有替换Spam.produce_spam,只需'produce_spam'在其中一个实例上查找名称时,就会先找到它.

本质上,继承的结果是,如果在对子类进行属性查找之后,在子类的字典中找不到该属性,那么任何基类的字典也将被搜索.

get_spam首次调用函数时:

s = SuperSpam()
s.get_spam()
Run Code Online (Sandbox Code Playgroud)

事件的顺序大致如下:

  • 看看SuperSpams __dict__for get_spam.
  • 因为它没有在SuperSpams中__dict__查找它的基类(mro链)的字典.
  • Spammro链中是下一个,所以get_spamSpam字典中找到.

现在,当produce_spamget_spamwith 的主体中查找时self.produce_spam,序列要短得多:

  • 调查SuperSpam的(self)__dict__ 进行produce_spam.
  • 找到它,得到它并调用它.

produce_spam在第__dict__一个中被找到以便获取.


Ter*_*edy 8

class Base():
    def m1(self):
        return self.m2()
    def m2(self):
        return 'base'

class Sub(Base):
    def m2(self):
        return 'sub'

b = Base()
s = Sub()
print(b.m1(), s.m1())
Run Code Online (Sandbox Code Playgroud)

打印"base sub"