如何在抽象类中调用非抽象方法?

时间:2019-08-23 20:34:03

标签: python abstract-class

我在python中有一个抽象类,想在其中调用非抽象方法。有可能做到吗?

from abc import ABC, abstractmethod
class MyAbstract(ABC):

# Can I call method get_state() from get_current() ?
def get_state():
   get_current()  # gives me error?

def get_current():

@abstractmethod
def get_time():

我还有另一个python文件,Temp.py实现了此接口。 在Temp.py中,我使用get_state调用MyAbstract.get_state(),但收到错误消息指出get_current()未定义。

不确定为什么。

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

通常,所有方法都有一个名称空间,该名称空间是它们所附加的类或对象。如果您有一个浮动的类的实例(例如,在大多数情况下,例如self),则可以在该实例上调用将实例本身作为第一个参数自动传递的方法-该实例充当实例方法的命名空间

如果您使用的是类方法或静态方法,则名称空间几乎总是成为它们所附加的类。如果未指定名称空间,则python会假定您要调用的任何函数都在全局名称空间中,否则,您会得到一个NameError

在这种情况下,以下内容适用于您:

class MyAbstract(ABC):
    def get_current():
        print("current")

    def get_state():
        MyAbstract.get_current()

    @abstractmethod
    def get_time():
        pass

您可以想象您在@staticmethod上方悬挂着一个不可见的get_current()装饰器,并以此进行了标记。这样做的问题在于,现在您不必更改子类中的get_current()的行为来影响get_state()中的更改。解决方案是使get_state()为类方法:

    @classmethod
    def get_state(cls):
        cls.get_current()

调用静态方法的语法与调用类方法的语法相同(在两种情况下,您都可以使用MyAbstract.get_state(),但后者会通过您在其上调用它的作为第一个方法然后,您可以使用此类作为命名空间,为最近定义了子类的任何子类找到方法get_current(),这就是如何使用否则会是静态的方法实现多态。