繁体   English   中英

父母的 class 方法能否调用将在子 class 中实现的抽象方法?

[英]Can a parent's class method call an abstract method which will be implemented in a child class?

如果我有一个父母 class 有两种方法:

class Parent():
    @abstractmethod
    @staticmethod
    def functionA():
       pass
    
    def functionB():
       return __class__.functionA() + 1

我实现了一个孩子 class:

class Child(Parent):
    def functionA(): # this function is different for each kind of child
        return 3

最后,子类的目的只是调用functionB() 它有效吗? 当然,我可以将functionB()放入子 class 并使其工作,但是因为functionB()对于每种子 class 都是相同的,我不想为每个 ZA2F2ED4F8EBC2CBB4C21A29DC40 编写重复代码?

另外,我在这里使用__class__合适吗?

首先, functionB本身应该是一个 class 方法。

@classmethod
def functionB(cls):
    return cls.functionA() + 1

其次,您仍然必须在每个子 class 中将functionA装饰为 static 方法; 否则,您将用实例方法替换继承的 static 方法。

class Child(Parent):

    @staticmethod
    def functionA():
        return 3

这是一个工作版本:

from abc import ABC, abstractmethod

class Parent(ABC):
    @staticmethod # not needed, but is documentation
    @abstractmethod
    def a(): pass

    @classmethod
    def b(cls): return cls.a() + 1

class Child(Parent):
    @staticmethod
    def a(): return 3

我们可以测试一下:

>>> c = Child()
>>> c.b()
4

值得注意的事情:

  • 我们需要使用ABC基础 class(或ABCMeta元类)才能访问abstractmethod装饰器,如abc模块文档中所述。

  • __class__不是关键字; 它是对象的属性 我们不能只做__class__.a()之类的事情,因为没有什么可以从__class__获取 我们可以使用普通方法的self参数来解决这个问题,但我们在这里真正想要做的是获得不需要实例的行为,但取决于我们使用的派生 class 这就是classmethod的用途,以及为什么有单独的classmethodstaticmethod装饰器。

当您使用classmethod时, class 将作为参数传递,就像您使用普通方法时如何传递实例一样。 按照惯例,我们将其命名为cls 有关classmethod的更多信息,请参阅Raymond Hettinger 的精彩演讲(在 Python 开发团队中)

  • 我们的抽象方法的实现也必须在子类中进行装饰,因为它们仍然不是普通的方法——所以 Python 需要知道不要传递实例。

  • 出于技术原因,需要首先列出抽象方法上的staticmethod方法修饰,在abstractmethod方法修饰之前。 它在这里实际上什么都不做。 当我们调用例如Parent.a()时, abstractmethod方法已经表现得像一个staticmethod方法(没有实例;我们无论如何都不能创建一个,因为它是一个抽象类)。

  • 对于a方法,我们也可以使用classmethod而不是staticmethod 这将允许Child的子级继承Child行为,而无需显式编写自己的a实现。 在这种情况下,我们希望在基本抽象方法上显式地修饰classmethod ,而不是staticmethod 当然,我们需要为每个a添加cls参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM