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

问题描述 投票:0回答:2

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

所以我的玩具模块是这样的。

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()

派生类.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,我得到了抽象名称导入错误。

我如何正确组织这个问题?

python static abstract-class static-methods
2个回答
0
投票

... 在基类中,我需要有一个共同的方法,它将使用一个特定的导入派生类的静态方法。

如果我对你的问题理解正确的话,我会说这个功能是开箱即用的,但有一个小例外。不要使用静态方法,只需使用普通的实例方法。

在基类中定义一个抽象方法,将确保派生类包含该方法的实现。而且,开箱即用,在派生类中定义的方法会在你调用 derived_object.bar().


0
投票

另一方面,如果你绝对需要在没有对象实例的情况下做这件事,可以用classmethods而不是staticmethods来做。

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"
© www.soinside.com 2019 - 2024. All rights reserved.