小能豆

在 Python 中,如何从子类调用父类的方法?

javascript

在 Python 中创建一个简单的对象层次结构时,我希望能够从派生类调用父类的方法。在 Perl 和 Java 中,有一个关键字 this ( super)。在 Perl 中,我可能会这样做:

package Foo;

sub frotz {
    return "Bamf";
}

package Bar;
@ISA = qw(Foo);

sub frotz {
   my $str = SUPER::frotz();
   return uc($str);
}

在 Python 中,似乎我必须明确地从子类中命名父类。在上面的例子中,我必须执行类似 的操作Foo::frotz()

这似乎不对,因为这种行为使得建立深层次结构变得困难。如果子代需要知道哪个类定义了继承的方法,那么就会产生各种信息痛苦。

这是 Python 的实际限制、我的理解上的差距,还是两者兼而有之?


阅读 26

收藏
2024-07-09

共2个答案

小能豆

使用super()函数:

class Foo(Bar):
    def baz(self, **kwargs):
        return super().baz(**kwargs)

对于 Python <3,您必须明确选择使用新式类并使用:

class Foo(Bar):
    def baz(self, arg):
        return super(Foo, self).baz(arg)
2024-07-09
小能豆

在 Python 中,您确实可以使用函数从父类调用方法super()。但是,语法和行为与 Perl 或 Java 等语言略有不同。让我们阐明如何在 Python 中实现这一点:

super()在 Python 中使用

Python 的super()函数提供了一种从父类访问方法和属性的方法。以下是使用 Python 重写示例的方法:

Python复制代码class Foo:
    def frotz(self):
        return "Bamf"

class Bar(Foo):
    def frotz(self):
        str_from_parent = super().frotz()  # Using super() to invoke parent method
        return str_from_parent.upper()

# Usage
bar_instance = Bar()
print(bar_instance.frotz())  # Outputs: "BAMF"

解释:

  1. 父类定义(Foo
  2. frotz()定义一个返回的方法"Bamf"
  3. 子类定义(Bar
  4. 继承自Foo
  5. 重写frotz()方法来修改行为。
  6. 用于从父类super()调用方法。frotz()``Foo
  7. 使用super()
  8. super()Python 中会根据类的方法解析顺序(MRO)自动解析要使用的适当类。
  9. 它确保您从继承层次结构中的下一个类调用该方法。
  10. 这种方法在 Python 中是首选,因为它尊重方法解析顺序,即使在复杂的类层次结构中也能正常工作。

关键点:

  • 显式命名:与 Perl ( Foo::frotz()) 或 Java ( super.frotz()) 不同,Python 用于super().frotz()动态调用父类的方法。
  • 动态解析super()是动态的,并遵循方法解析顺序(MRO)来确定从中调用方法的正确类。
  • 多重继承super()在 Python 的多重继承场景中特别有用,它可以确保根据 MRO 以正确的顺序调用方法。

结论:

在 Python 中使用super()可让您有效地从父类调用方法,而无需明确命名它们。这种方法旨在促进代码维护,并支持 Python 的可读性和简单性理念。它的语法和行为可能与其他语言不同,但它利用 Python 的动态特性和 MRO 在类层次结构中有效地解析方法。

2024-07-09