【问题标题】:Python Inherit from one class but override method calling another class?Python从一个类继承但覆盖调用另一个类的方法?
【发布时间】:2015-09-22 11:18:50
【问题描述】:

假设我有 3 个类:A、B 和 C。A 是 B 的基类,B 是 C 的基类。层次结构通常保存在这里,但对于一种方法,它应该是不同的。对于 C 类,它应该表现得像从 A 继承。

例如这样:

class A(object):
    def m(self):
        print 'a'

class B(A):
    def m(self):
        super(B, self).m()
        print 'b'

class C(B):
    def m(self):
        super(A, self).m()
        print 'c'

所以基本上它应该像这样工作:

a = A()
a.m()
a

b = B()
b.m()
a
b

c = C()
c.m()
a
c

但它不适用于 C 类,因为我收到此错误:

AttributeError: 'super' object has no attribute 'm'

为了解决这个问题,我可以从类 A 继承 C 类,但我想从 B 继承所有内容,并且对于特定方法 m 为基类 A 调用 super。我的意思是该方法是一个例外。或者我应该为 C 类以某种不同的方式调用它才能工作?

我该怎么做?

【问题讨论】:

  • 你试过A.m(self)而不是super吗?
  • @MathiasEttinger 不,我没有,但现在我试过了,它工作得很好。谢谢。您可以将其发布为答案,因为它解决了我的问题
  • 为了让它工作,A.m() 必须是一个类方法
  • 不,这是一个未绑定的方法,您正在手动提供self 参数
  • @Andrius 似乎你对super() 感到困惑。 super(SomeClass, someobject) 将在someobject 的MRO 中遵循 SomeClass 的类中查找属性。在您的情况下,super(A, self).m() 指的是object.m(self),这显然不存在。

标签: python oop inheritance super


【解决方案1】:

实际上有两种方法可以解决这个问题:您可以将调用快捷方式到 super() 并完全绕过 mro,就像 Mathias Ettinger 的回答中一样,或者您可以直接向 @ 发出 正确 调用987654322@:

class C(B):
    def m(self):
        super(B, self).m()
        print 'c'

请记住,super() 期望它应该开始查找 mro 的类作为第一个参数。它通常是调用所在的类,但如果你愿意,你可以在 mro 中传递另一个类。

【讨论】:

    【解决方案2】:

    使用super 调用,python 将检查您的类的MRO 以确定在调用您想要的函数时使用哪个类。

    由于您想缩短此行为,您可以明确声明要使用该方法的类:

    class C(B):
        def m(self):
            A.m(self)
            print 'c'
    

    【讨论】:

      猜你喜欢
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多