【问题标题】:Inherit same function name from several classes从多个类继承相同的函数名
【发布时间】:2017-12-13 20:07:54
【问题描述】:

我正在阅读 stackoverflow 上的 this 线程,但根据用户的说法,该解决方案似乎是错误的,最重要的是,它无法解决我的问题,我不知道是不是因为答案是在 python 2 中还是什么。

但是,假设我有这个代码

class A:
    def say_hello(self):
        print("Hi")

class B:
    def say_hello(self):
        print("Hello")

class C(A, B):
    def say_hello(self):
        super().say_hello()
        print("Hey")

welcome = C()
welcome.say_hello()

如何在不更改函数名称的情况下从 C 类调用 A 类和 B 类? 正如我在另一个线程中所读到的,您可以执行super(B, self).say_hello() 之类的操作,但这似乎不起作用,但我不知道为什么。

【问题讨论】:

  • “似乎不起作用”是什么意思?您是否收到任何类型的错误消息?输出错误?
  • 要详细说明 Davy 的评论,您期望的输出是什么?你得到什么输出?您的问题“我如何从 C 类中调用 A 类和 B 类”尚不清楚 - 但我认为您只想要 A.say_hello(self) 然后是 B.say_hello(self)。 super 将使用 MRO 中的下一个类。如果您不想枚举实际值,那么您将不得不提供更多详细信息...
  • 您对super 的调用调用了A.say_hello,但该方法没有调用super,因此调用链结束。

标签: python python-3.x class inheritance


【解决方案1】:

要正确使用super,涉及的每个类都需要正确设计。除其他事项外:

  1. One 类应该是该方法的“根”,这意味着它不会使用super 来进一步委托调用。该类必须出现在提供该方法的任何其他类之后。

  2. 所有非根类必须使用super 来传递来自任何其他可能定义该方法的类的调用。


# Designated root class for say_hello
class A:
    def say_hello(self):
        print("Hi")

# Does not inherit say_hello, but must be aware that it is not the root
# class, and it should delegate a call further up the MRO
class B:
    def say_hello(self):
        super().say_hello()
        print("Hello")

# Make sure A is the last class in the MRO to ensure all say_hello
# methods are called.
class C(B, A):
    def say_hello(self):
        super().say_hello()
        print("Hey")

welcome = C()
welcome.say_hello()

这里,C.say_hello 中的super 将调用B.say_hello,其super 将调用A.say_hello。


如果您不想满足使用super 的要求,只需显式调用其他类的方法即可。使用super 没有要求。

class A:
    def say_hello(self):
        print("Hi")

class B:
    def say_hello(self):
        print("Hello")

class C(A, B):
    def say_hello(self):
        A.say_hello(self)
        B.say_hello(self)
        print("Hey")

【讨论】:

  • 在C 的定义中,超类的顺序是否重要?
  • 是的;如果 A 在 B 之前,那么 A.say_hello 将始终在 B.say_hello 之前被调用,这将完全阻止 B.say_hello 被调用。
  • 非常有趣,我不知道调用的顺序很重要:所以如果你像我一样调用 class(A,B) 它不起作用,但如果你这样做 B ,A 它有效。感谢您的帮助和解释
  • @chepner 在您的解决方案中,谁是 B 的父母?当你在 B 中使用 super().say_hello() 时,你调用的是哪个父方法?
  • B 的父级是object,但在B.sayhello 中,您不知道接下来会访问哪个类super;这完全取决于 self 的运行时类型,其方法解析顺序 (MRO) 用于决定 B 之后的类。
猜你喜欢
  • 2013-08-26
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 2023-03-03
  • 2013-01-03
  • 1970-01-01
相关资源
最近更新 更多