问题:如何在python抽象类中创建抽象属性
在以下代码中,我创建了一个基本抽象类Base
。我希望所有从其继承的类都Base
提供该name
属性,因此我将该属性设置为@abstractmethod
。
然后,我创建了一个Base
名为的子类,该子类Base_1
旨在提供一些功能,但仍保持抽象。中没有name
属性Base_1
,但是python实例化了该类的对象而没有错误。一个人如何创建抽象属性?
from abc import ABCMeta, abstractmethod
class Base(object):
__metaclass__ = ABCMeta
def __init__(self, strDirConfig):
self.strDirConfig = strDirConfig
@abstractmethod
def _doStuff(self, signals):
pass
@property
@abstractmethod
def name(self):
#this property will be supplied by the inheriting classes
#individually
pass
class Base_1(Base):
__metaclass__ = ABCMeta
# this class does not provide the name property, should raise an error
def __init__(self, strDirConfig):
super(Base_1, self).__init__(strDirConfig)
def _doStuff(self, signals):
print 'Base_1 does stuff'
class C(Base_1):
@property
def name(self):
return 'class C'
if __name__ == '__main__':
b1 = Base_1('abc')
回答 0
从Python 3.3开始,修复了一个错误,这意味着property()
装饰器现在应用于抽象方法时,可以正确地标识为抽象。
注:订单的问题,你必须使用@property
前@abstractmethod
Python 3.3以上版本:(python docs):
class C(ABC):
@property
@abstractmethod
def my_abstract_property(self):
...
Python 2:(python docs)
class C(ABC):
@abstractproperty
def my_abstract_property(self):
...
回答 1
在Python 3.3之前,您不能嵌套@abstractmethod
和@property
。
使用@abstractproperty
创建抽象属性(文档)。
from abc import ABCMeta, abstractmethod, abstractproperty
class Base(object):
# ...
@abstractproperty
def name(self):
pass
该代码现在引发正确的异常:
追溯(最近一次通话): 在第36行的文件“ foo.py”中 b1 = Base_1('abc') TypeError:无法使用抽象方法名称实例化抽象类Base_1
回答 2
根据上面的詹姆斯回答
def compatibleabstractproperty(func):
if sys.version_info > (3, 3):
return property(abstractmethod(func))
else:
return abstractproperty(func)
并将其用作装饰器
@compatibleabstractproperty
def env(self):
raise NotImplementedError()