【问题标题】:Redefining methods through class inheritance in Python通过 Python 中的类继承重新定义方法
【发布时间】:2021-06-19 09:25:02
【问题描述】:

我正在玩类继承,我想知道是否可以在不重写整个事情的情况下更改子类中继承方法的各个方面?

例如:

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 方法,在父类中定义。其中a 取决于ybool 参数通过Child1 中的重写方法传递:

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

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

【问题讨论】:

  • 是可以的,你需要将你想要定制的部分提取到他们自己的方法中,这样每个子类都可以只修改那个部分。

标签: python python-3.x inheritance methods subclass


【解决方案1】:

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

使用“私有”方法

例如:

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

在此示例中,所有子类都将继承 _foo“private”函数,它们可能会或可能不会收到 a 的值。

使用抽象类

对于这个问题还有另一个解决方案是抽象类(这里是一个example 说明如何做到这一点),你可以强制子类实现函数foo

重要

记住,在抽象类的情况下,如果你没有定义用@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

【讨论】:

  • 这太棒了@GustavoPedroni,谢谢!
猜你喜欢
  • 2020-06-06
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 2021-02-21
  • 2014-09-13
相关资源
最近更新 更多