简体   繁体   English

生成抽象基类Python

[英]Generating an abstract base class Python

Problem: 问题:

I'd like to generate an abstract class with a few method stubs that should be implemented by its sub-classes thereby avoiding any hard-coding. 我想生成一个带有一些方法存根的抽象类,该方法存根应由其子类实现,从而避免进行任何硬编码。

That is, if I define a class as follows: 也就是说,如果我定义一个类如下:

>>> class Sample(SomeClass):    
...    ACTIONS = ('run', 'sleep', 'kill')

The above class should always implement the methods run , sleep , and kill . 上面的类应该始终实现runsleepkill

Attempted solution: 尝试的解决方案:

The snippet below works as expected and raises an error when the abstract method run is not defined in subclass FooBar . 下面的代码段按预期方式工作,并且在子类FooBar未定义抽象方法run时会引发错误。

>>> class Foo(object):
...     __metaclass__ = ABCMeta
...     
...     @abstractmethod
...     def run(self, *args, **kwargs):        
...         pass    


>>> class FooBar(Foo):
...     def __init__(self, a, b):
...         self.a = a
...         self.b = b

>>> FooBar(1, 2)        
TypeError: Can't instantiate abstract class FooBar with abstract methods run

I was trying to achieve the same by generating the Foo class using type : 我试图通过使用type生成Foo类来实现相同目的:

>>> Foo2 = type('Foo', (), {'__metaclass__': ABCMeta, 
...                         'run'          : abstractmethod(lambda self, *args, **kwargs: None)})

>>> class FooBar(Foo2):
...     def __init__(self, a, b):
...         self.a = a
...         self.b = b

However, the below call does not raise any error: 但是,以下调用不会引发任何错误:

>>> FooBar(1, 2)        
<__main__.FooBar at ...>

Noticed that __abstractmethods__ doesn't get defined in Foo2 (comparing vars(Foo) and vars(Foo2) ). 注意在__abstractmethods__中没有定义Foo2 (比较vars(Foo)vars(Foo2) )。

I did find a similar attempt here , but wasn't able to follow why the above wouldn't work and why I can't make use of ABCMeta directly (which defines __new__ in a generic manner). 我在这里确实找到了类似的尝试,但是无法理解为什么上面的方法行不通以及为什么我不能直接使用ABCMeta (以通用方式定义__new__ )。

Realized I could just do this :) 意识到我可以做到这一点:)

>>> Foo2 = ABCMeta('Foo', (), {'run': abstractmethod(lambda self, *args, **kwargs: None)})

>>> FooBar(1, 2)
TypeError: Can't instantiate abstract class FooBar with abstract methods run

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

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