简体   繁体   English

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

[英]Redefine abstract method as static method and call it from base class

Suppose I need to implement an abstract Python interface which then will have many derived classes (each named equally but written in different modules), and in base class I heed to have a common method which will use a particular imported derived class' static method.假设我需要实现一个抽象的 Python 接口,然后它将有许多派生类(每个类命名相同但编写在不同的模块中),并且在基类中我注意到有一个通用方法,它将使用特定的导入派生类的静态方法。

So my toy modules look like this:所以我的玩具模块看起来像这样:

abstract_class.py抽象类.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派生类.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()

Then of course when I'm trying to run derived_class.py , I get the Abstract name import error.然后,当然,当我尝试运行derived_class.py ,我收到了抽象名称导入错误。

How do I properly organize this?我如何正确组织这个?

On the other hand, if you absolutely needed to do this without an object instance, it's possible to do with classmethods rather than 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"

... in base class I heed to have a common method which will use a particular imported derived class' static method ...在基类中,我注意到有一个通用方法,它将使用特定导入的派生类的静态方法

If I understand your question correctly, I'd say that this functionality is available out of the box with one small exception: Don't use a static method;如果我正确理解你的问题,我会说这个功能是开箱即用的,只有一个小例外:不要使用静态方法; just use a regular instance method.只需使用常规实例方法。

Defining an abstract method in the base class will ensure that derived classes contain an implementation for that method.在基类中定义抽象方法将确保派生类包含该方法的实现。 And, out of the box, the method defined in the derived class will get called when you call derived_object.bar() .而且,开箱即用,派生类中定义的方法将在您调用derived_object.bar()时被调用。

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

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