2013-02-03 120 views
2

按照docs它應該工作結合@property@abc.abstractmethod所以下面應該python3.3工作:abc.abstractmethod +物業

import abc 

class FooBase(metaclass=abc.ABCMeta): 

    @property 
    @abc.abstractmethod 
    def greet(self): 
     """ must be implemented in order to instantiate """ 
     pass 

    @property 
    def greet_comparison(self): 
     """ must be implemented in order to instantiate """ 
     return 'hello' 

class Foo(FooBase): 
    def greet(self): 
     return 'hello' 

測試執行:

In [6]: foo = Foo() 
In [7]: foo.greet 
Out[7]: <bound method Foo.greet of <__main__.Foo object at 0x7f935a971f10>> 

In [8]: foo.greet() 
Out[8]: 'hello' 

所以顯然不是財產,因爲那麼它應該這樣工作:

In [9]: foo.greet_comparison 
Out[9]: 'hello' 

也許我是愚蠢的,或者根本行不通,有人有想法?

回答

3

如果你想greet是一個屬性,你仍然需要使用@property裝飾中的實現:

class Foo(FooBase): 
    @property 
    def greet(self): 
     return 'hello' 

所有這一切的ABC元類的作用是測試用是否您提供同名具體的課堂;它不關心它是一種方法還是屬性或常規屬性。

因爲它不在意,它也不會神奇地應用property裝飾者。這是一個好的的事;也許在一個特定的實現中,一個靜態屬性足以滿足要求,而一個屬性將是矯枉過正的。

ABC元類的目的是幫助您檢測實現中的差距;它從來沒有打算執行這些屬性的類型。

請注意,在Python 3.3之前,您不能將@property@abstractmethod合併。您將不得不使用@abstractproperty decorator。當你的財產在這種情況下需要的不僅僅是一個簡單的吸氣器時,那裏有一個模棱兩可的問題; Python 3.3涵蓋的情況要好得多(有關痛苦細節,請參見issue 11610)。

+0

只是打我:) –

+0

如果你有一個抽象的二傳手,會裝飾迎接滿足覆蓋要求?只是一個興趣點。 –

+0

@ m.brindley:如果'問候在dir(Foo)'工作,它滿足作爲覆蓋。看看這個[我以前的答案](http://stackoverflow.com/questions/14441619/actual-difference-in-implementing-overriding-using-abstractproperty-and-abstra/14441682#14441682)關於如何ABC檢查覆蓋。 –