4

根据文档,它应该可以结合起来@property@abc.abstractmethod因此以下内容应该在 python3.3 中工作:

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'

也许我太笨了,或者它根本不起作用,有人有想法吗?

4

1 回答 1

8

如果你想greet成为一个属性,你仍然需要@property在你的实现中使用装饰器:

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

ABC 元类所做的只是测试您是否在具体类中提供了相同的名称;它不关心它是方法、属性还是常规属性。

因为它不在乎,所以它也不会神奇地应用property装饰器。这是一件好事;也许在特定的实现中,静态属性足以满足要求,而属性将是矫枉过正。

ABC 元类的目的是帮助您发现实现中的差距;它从来没有打算强制执行属性的类型。

请注意,在 Python 3.3 之前,您不能将 a@property@abstractmethod. 您将不得不使用@abstractproperty装饰器。在这种情况下,当您的属性需要的不仅仅是一个简单的 getter 时,就会出现歧义;Python 3.3 更好地涵盖了这种情况(有关痛苦的细节,请参阅issue 11610)。

于 2013-02-03T09:38:09.940 回答