2011-05-11 200 views
43

在下面的代碼中,我創建了一個基本抽象類Base。我想要從Base繼承的所有類提供name屬性,所以我將此屬性設置爲@abstractmethod如何在python抽象類中創建抽象屬性

然後我創建了Base的一個子類,名爲Base_1,它意在提供一些功能,但仍然是抽象的。 Base_1中沒有name屬性,但是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

疑難雜症:如果你忘了'類C'使用裝飾'@ property','name'將恢復的方法。 – kevinarpe 2014-11-02 05:35:09

回答

3

由於Python 3.3一個錯誤是固定意味着property()裝飾當施加到一個抽象方法現在正確地識別爲抽象。

python docs

class C(ABC): 
    @property 
    @abstractmethod 
    def my_abstract_property(self): 
     ... 
34

直到Python 3.3,你不能嵌套@abstractmethod@property

使用@abstractproperty創建抽象屬性(docs)。

from abc import ABCMeta, abstractmethod, abstractproperty 

class Base(object): 
    # ... 
    @abstractproperty 
    def name(self): 
     pass 

代碼現在提出了正確的例外:

 
Traceback (most recent call last): 
    File "foo.py", line 36, in 
    b1 = Base_1('abc') 
TypeError: Can't instantiate abstract class Base_1 with abstract methods name 
+28

實際上這個答案對於年輕的python來說是錯誤的:從3.3開始,'@ abstractproperty'被棄用,贊成像OP這樣的組合。 – 2012-11-09 20:18:36

+10

從3.3文檔:http://docs.python.org/3/library/abc.html#abc.abstractproperty – codeape 2012-11-12 08:40:51

+0

謝謝,codeape。我會相應地更新答案。 – 2012-11-12 13:45:45