【问题标题】:python multiple inheritance calling overridden functions in super contextpython多重继承在超级上下文中调用重写的函数
【发布时间】:2016-06-30 10:27:06
【问题描述】:

(Python 3)

我正在尝试使用一些新奇的格式化例程来扩展一个类,但是我也希望能够在基类中使用格式化例程。

class Plaintext(object):
    def print_thing(self, thing):
        print("plain", thing)

    def print_blob(self, blob):
        for thing in blob:
            self.print_thing(thing)

    def print_goober(self, blob):
        print("plaintext")
        self.print_blob(blob)

class Markdown(Plaintext):
    def print_thing(self, thing):
        print("mark", thing)

    def print_goober(self, blob):
        print("markdown")
        self.print_blob(blob)
        super().print_blob(blob)

newclass = Markdown()
newclass.print_goober([1,2,3])

运行时,我得到:

markdown
mark 1
mark 2
mark 3
mark 1
mark 2
mark 3

如何让 newclass.print_goober() 先在自身上下文中调用 print_blob(),然后在 BaseClass 上下文中调用?

我试图得到的输出是:

markdown
mark 1
mark 2
mark 3
plain 1
plain 2
plain 3

我需要创建某种 mixin 吗?

【问题讨论】:

  • 您的 print_thing() 方法在子类中被覆盖。这就是为什么它打印所有marks
  • 调用 super 的语法错误。应该是super(Markdown, self).print_blob(blob)
  • @naveenyadav -- 在 python3.x 中引入了无参数super() 快捷方式。
  • 我知道 print_thing() 正在被覆盖。但是,我希望能够在 print_thing() 不会被覆盖的上下文中调用 print_blob。 print_blob 是一个大而复杂的函数,所以重点是不要复制代码只是为了覆盖一个小东西以支持降价。
  • @PaulT。 -- Python 支持对前缀为 __ 的名称进行名称修改 -- 例如__name。解释器实际上将这样的名称更改为_classname__name。问题是子类很难调用__name(除非你自己修改名字——这绝对是一个hack)。

标签: python multiple-inheritance mixins super


【解决方案1】:

所以...self 很好...self。在您的示例中,每次调用self,它Markdown 的实例,外部称为newclass

当您这样想时,self.print_thing 会按照您的预期行事。它查找它可以找到的第一个print_thing 方法,然后使用self 作为第一个参数调用它。

好的,现在我们已经整理好了……我们如何做你想做的事?好吧,(我不能说得足够强烈)没有干净的方法可以做到这一点,而不是更明确地说明你真正想要什么。在这种情况下,我建议让markdown 定义调用旧方法的新方法:

class Plaintext(object):
    def print_thing(self, thing):
        print("plain", thing)

    def print_blob(self, blob):
        for thing in blob:
            self.print_thing(thing)

    def print_goober(self, blob):
        print("plaintext")
        self.print_blob(blob)

class Markdown(Plaintext):
    def print_markdown_thing(self, thing):
        print("mark", thing)

    def print_markdown_blob(self, blob):
        for thing in blob:
            self.print_markdown_thing(thing)

    def print_goober(self, blob):
        print("markdown")
        self.print_markdown_blob(blob)
        self.print_blob(blob)

newclass = Markdown()
newclass.print_goober([1,2,3])

【讨论】:

  • 不幸的是,我试图避免这种情况,因为 print_blob() 是一个复杂的例程并且会涉及代码复制。
猜你喜欢
  • 1970-01-01
  • 2018-04-22
  • 2020-02-29
  • 1970-01-01
  • 2016-09-03
  • 1970-01-01
  • 2012-07-06
  • 2015-12-28
  • 1970-01-01
相关资源
最近更新 更多