在 Python 中通过 class 继承重新定义方法

Redefining methods through class inheritance in Python

我正在研究 class 继承,我想知道是否可以在子 class 中更改继承方法的各个方面而不必重写整个方法?

例如:

class Parent:
    def _init_(self, x):
        self.x = x

    def foo(self):
        a = self.x
        if a > 0:
            forward = True
        elif a < 0:
            forward = False
        return forward

class Child1(Parent):
    def foo(self, y=None, bool=False):
        if bool:
            a = y
        else:
            a = self.x
        super().foo()

class Child2(Parent):
        pass

我正在寻找的是如果我调用 Child1.foo 它可以在 运行 之前重新分配变量 a 父 class 中定义的方法。其中 a 依赖于 ybool 参数通过 Child1 中重写的方法传递:

print(Child1(2).foo(-2, True))
# => False
print(Child1(2).foo())
# => True
print(Child2(2).foo())
# => True

这可能吗,还是我只需要为每个 class 重写一个新方法?

我想我理解你的问题,我对你如何解决这个问题有一些建议:

使用“私有”方法

例如:

class Parent:
    def __init__(self, x):
        self.x = x

    def _foo(self, a=None):
        a = a if a else self.x * 2  
        
        if a > 10:
            over = True
        else:
            over = False

        return over

    def foo(self):
        return self._foo()

class Child1(Parent):

    def foo(self, y=None, condition=False):

        if condition:
            a = y*2
        else:
            a = self.x*2

        return self._foo(a)

class Child2(Parent):
    pass

在此示例中,所有子 classes 将继承 _foo“私有”功能,他们可能会或可能不会收到 a 的值。

使用摘要 classes

这个问题还有另一种解决方案,使用抽象 classes(这里是 example 如何做到这一点),你可以强制子 class 实现该功能foo:

重要

记得在abstract classes的情况下,如果你没有定义用@abstractmethod装饰的函数,你会收到类似这样的错误TypeError: Can't instantiate abstract class Child2 with abstract methods foo

示例:

Python 2.x

from abc import ABCMeta, abstractmethod

class Parent:
    __metaclass__ = ABCMeta

    def __init__(self, x):
        self.x = x

    def _foo(self, a=None):
        a = a if a else self.x * 2  
        
        if a > 10:
            over = True
        else:
            over = False

        return over

    @abc.abstractmethod
    def foo(self):
        pass

class Child1(Parent):

    def foo(self, y=None, condition=False):

        if condition:
            a = y*2
        else:
            a = self.x*2

        return self._foo(a)

class Child2(Parent):

    def foo(self):
        return self._foo()

Python 3.x

class Parent(metaclass=ABCMeta):

    def __init__(self, x):
        self.x = x

    def _foo(self, a=None):
        a = a if a else self.x * 2  
        
        if a > 10:
            over = True
        else:
            over = False

        return over

    @abc.abstractmethod
    def foo(self):
        pass

class Child1(Parent):

    def foo(self, y=None, condition=False):

        if condition:
            a = y*2
        else:
            a = self.x*2

        return self._foo(a)

class Child2(Parent):

    def foo(self):
        return self._foo()

在这两个示例中,您将通过 运行 得到相同的结果:

print(Child1(2).foo(10, True)) // True
print(Child1(2).foo()) // False
print(Child2(2).foo()) // False