将抽象方法重新定义为静态方法,并从基类中调用它

时间:2015-01-14 14:34:48

标签: python static abstract-class static-methods

假设我需要实现一个抽象的Python接口,然后它将有许多派生类(每个都是相同的,但是在不同的模块中编写),而在基类中我注意到有一个常用的方法,它将使用特定的导入派生类&# 39;静态方法。

所以我的玩具模块看起来像这样:

abstract_class.py

 from abc import ABCMeta, abstractmethod

 from derived_class import Derived

 class Abstract:
   __metaclass__ = ABCMeta

   @abstractmethod
   def foo(self):
     pass

   def bar(self):
     Derived.foo()

derived_class.py

from abstract_class import Abstract

class Derived(Abstract):
  @staticmethod
  def foo():
    print 'Good news everyone!'

if __name__ == '__main__':
  derived_object = Derived()
  derived_object.bar()

当然,当我试图运行derived_class.py时,我收到了抽象名称导入错误。

我如何正确组织这个?

2 个答案:

答案 0 :(得分:0)

...在基类中,我注意到有一个通用方法将使用 特定导入的派生类的静态方法

如果我正确理解了您的问题,我会说此功能是现成可用的,只有一个小例外:不要使用静态方法;请使用静态方法。只需使用常规实例方法即可。

在基类中定义抽象方法将确保派生类包含该方法的实现。并且,当您调用derived_object.bar()时,将立即调用派生类中定义的方法。

答案 1 :(得分:0)

另一方面,如果您绝对需要在没有对象实例的情况下执行此操作,则可以使用类方法而不是静态方法。

from abc import ABC, abstractmethod

class MyAbstractClass(ABC):

    @staticmethod
    @abstractmethod
    def foo(label: str):
        raise NotImplementedError()


    @classmethod
    def foo_agnostic(cls, label: str):
        """
        NOTE: Here, this method doesn't have a reference to an instance of the class.
        Instead, it only has a reference to the class itself; but that is enough
        to call the abstract static foo() method.
        """
        cls.foo(label)


class MyDerivedClass(MyAbstractClass):

    @staticmethod
    def foo(label: str):
        print(label)


if __name__ == "__main__":
    instance = MyDerivedClass()
    instance.foo("Test 1")                # Outputs "Test 1"
    instance.foo_agnostic("Test 2")       # Outputs "Test 2"
    MyDerivedClass.foo_agnostic("Test 3") # Outputs "Test 3"