我如何从Python的子类中称呼间接的父级方法?

发布于 2025-01-21 12:43:03 字数 508 浏览 4 评论 0原文

我有A,B和C类。C从A和B继承,并且在大多数情况下,有方法互相覆盖,我希望A覆盖B,所以我有以下结构:

class A:
    def some_method(self):
        return self.some_attribute

class B:
    def some_method(self):
        return self.some_other_attribute

class C(A,B):
    def some_method(self):
        var = super().some_method() -> this will give me the method from A, but I want the B one
        return var + 1

所以我的问题是如何如何我使用super()或其他方式调用some_method(),因此我可以在c中的方法中使用它?

同样为记录,我正在使用Python 3.**

I have classes A, B, and C. C inherits both from A and B, and for the most part wherever there are methods overriding each other I want A's to override B's, so I have the following structure:

class A:
    def some_method(self):
        return self.some_attribute

class B:
    def some_method(self):
        return self.some_other_attribute

class C(A,B):
    def some_method(self):
        var = super().some_method() -> this will give me the method from A, but I want the B one
        return var + 1

So my question is how can I invoke with super() or some other way the some_method() from B, so I can use it in the method override in C?

Also for the record I am using Python 3.*

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

偏爱自由 2025-01-28 12:43:03

Python是一种具有多种继承的语言,这意味着类可以具有几个直接超类。但是,为了调用super(),python始终线性化的继承层次结构以确定谁是“最佳”超级类别。这就是称为方法解决顺序,通过<代码> __ Mro __ python中的变量。

因此,如果我们具有类层次结构

class A(object): pass
class B(A): pass
class C(A): pass
class D(B, C): pass

,则虽然d有两个超级类,如果我们在d中说super(),它只会给我们b。这是因为d的MRO为我们创建了线性层次结构。在Python 3中,它使用了一种称为 C3分辨率的算法

>>> D.__mro__
(<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>)

我们在类d上的方法中调用super(),我们将在b上获取版本,如果我们调用super super ()从那里,我们将获得c版本,然后获得a版本,最后是Object一个。

因此,就您而言,cab(按此顺序)继承,因此它将偏向于a < /代码>。也就是说,示例中类c的MRO是(c,a,b,object)。如果您希望它能始终 b然后 a ,则只需切换超级类的顺序即可。

class C(B, A):
  ...

这是最好的解决方案。它的可预测性,Python程序员将立即了解此类中super()调用的意图。如果适合您的需求,我建议这样做。

但是,如果您有一个复杂的多启示系统,并且需要访问 ab超级类直接使用类名称致电他们,放弃super()完全致电。

class C(B, A):
  def some_method(self):
    A.some_method(self) # Calls A's version on self
    B.some_method(self) # Calls B's version on self

如果some_method进行一些参数,则可以在显式self参数之后通过它们。这将引起更多的眉毛,因此,如果您发现自己需要以复杂的方式访问两种不同的超类方法,则可以考虑重构代码以使用较少的多重继承。但是,如果您确实需要它,则该功能就在那里。

Python is a language with multiple inheritance, which means that a class can have several direct superclasses. But for the purposes of calling super(), Python always linearizes the inheritance hierarchy to determine who the "best" superclass is. This is called the method resolution order, accessed via the __mro__ variable in Python.

So if we have the class hierarchy

class A(object): pass
class B(A): pass
class C(A): pass
class D(B, C): pass

Then although D has two superclassses, if we say super() in D, it'll only give us B. That's because the MRO for D creates a linear hierarchy for us. In Python 3, it uses an algorithm called the C3 resolution, which gives us this hierarchy

>>> D.__mro__
(<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>)

So if we call super() in a method on class D, we'll get the version on B, and if we call super() from there, we'll get the C version, then the A version, and finally the object one.

So in your case, C inherits from A and B (in that order), so it's going to be biased toward A. That is, the MRO for the class C in your example is (C, A, B, object). If you want it to always go for B and then A, then simply switch the order of the superclasses.

class C(B, A):
  ...

This is the best solution. It's predictable and Python programmers will immediately understand the intention of a super() call in this class. I recommend this if it fits your needs.

However, if you have a complicated multi-inheritance system and need access to both the A and B superclasses at the same time, you can always call them directly with a class name, forgoing the super() call altogether.

class C(B, A):
  def some_method(self):
    A.some_method(self) # Calls A's version on self
    B.some_method(self) # Calls B's version on self

If some_method takes some arguments, you can pass them after the explicit self argument. This is going to raise more eyebrows, so if you find yourself needing access to two distinct superclass methods in complicated ways, you might consider refactoring your code to use less multiple inheritance. But the feature is there if you really need it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文