关于python:在不更改父类方法名称的情况下向父类方法添加额外功能

Adding extra functionality to parent class method without changing its name

本问题已经有最佳答案,请猛点这里访问。

我有两个班,一个是家长,另一个是孩子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Parent(object):

    def __init__(self):
        #does something

    def method_parent(self):
        print"Parent"

class Child(Parent):

    def __init__(self):
        Parent.__init__(self)

    def method_parent(self):
        print"Child"

继承父方法之后,我想修改父方法method_parent,保留该方法的原始功能,并向该方法添加一些额外的代码行。

我知道我可以创造一种新的方法

1
2
3
def method_child(self):
    self.method_parent()
    #Add extra lines of code to perform something

但我想使用方法的原始名称。我无法复制该方法的源代码,因为该方法来自一个C模块

我想要达到的是这样的目标

1
2
3
def method_parent():
    #do parent_method stuff
    #do extra stuff

这是可能的吗?


您始终可以使用super()函数从父级调用代码。它提供了对父级的引用。所以,要调用parent_method(),应该使用super().parent_method()

这里有一个代码片段(用于python3),演示了如何使用它。

1
2
3
4
5
6
7
8
class ParentClass:
    def f(self):
        print("Hi!");

class ChildClass(ParentClass):
    def f(self):
        super().f();
        print("Hello!");

在python2中,需要用额外的参数调用super:super(ChildClass, self)。因此,代码片段将变成:

1
2
3
4
5
6
7
8
class ParentClass:
    def f(self):
        print("Hi!");

class ChildClass(ParentClass):
    def f(self):
        super(ChildClass, self).f();
        print("Hello!");

如果您在ChildClass实例上调用f(),它将显示:"嗨!你好!".

如果你已经用Java编码了,基本上是相同的行为。你可以随时随地打电话给Super。在方法中,在init函数中,…

还有其他的方法可以做到,但不太干净。例如,您可以执行以下操作:

1
ParentClass.f(self)

调用父类的f函数。


这就是super函数所做的。

1
2
3
4
5
6
7
8
class Child(Parent):

    def __init__(self):
        super(Child, self).__init__()

    def method_parent(self):
        super(Child, self).method_parent()
        print"Child"

在python 3中,可以不带参数调用super,如super().method_parent()


您可以完全按照用于__init__one的方法调用父方法:

1
2
3
4
5
6
7
8
class Child(Parent):

    def __init__(self):
        Parent.__init__(self)

    def method_parent(self):
        Parent.method_parent(self)  # call method on Parent
        print"Child"

当您想明确地命名父类时,就需要使用这个方法。如果您愿意,可以要求python按照方法解析顺序使用super给您下一个类:

1
2
3
    def method_parent(self):
        super(Child, self).method_parent()  # call method on Parent
        print"Child"