2013-02-03 72 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检查覆盖。 –