定义抽象实例属性而不是属性的最佳实践是什么?
我想写一些东西,比如:
class AbstractFoo(metaclass=ABCMeta):
@property
@abstractmethod
def bar(self):
pass
class Foo(AbstractFoo):
def __init__(self):
self.bar = 3
而不是:
class Foo(AbstractFoo):
def __init__(self):
self._bar = 3
@property
def bar(self):
return self._bar
@bar.setter
def setbar(self, bar):
self._bar = bar
@bar.deleter
def delbar(self):
del self._bar
属性是很方便的,但是对于不需要计算的简单属性来说,它们是一种过度的消耗。对于抽象类,这一点尤其重要,抽象类将由用户进行子类化和实现(我不想强迫某人使用@property
,因为他本来可以在__init__
中编写self.foo = foo
)。
Abstract attributes in Python问题建议作为使用@property
和@abstractmethod
的唯一答案:它不回答我的问题。
通过^{
到了2018年,我们应该得到更好的解决方案:
它的行为如下:
这个答案使用与公认答案相同的方法,但与内置的ABC很好地集成,不需要
check_bar()
helpers的样板。以下是
better_abc.py
内容:好在你可以做到:
工作原理同上。
也可以使用:
定义自定义ABC助手。另外,我认为这个代码是CC0。
这可以通过使用AST解析器通过扫描
__init__
代码来提高早期(在类声明上)的性能,但目前看来这是一个过度的牺牲(除非有人愿意实现)。仅仅因为在抽象基类上将其定义为
abstractproperty
,并不意味着必须在子类上创建属性。例如,您可以:
如果要初始化
__init__
中的值,可以执行以下操作:因为Python 3.3
abstractproperty
是deprecated。因此,Python 3用户应该使用以下内容:如果你真的想强制子类定义一个给定的属性,你可以使用元类。就我个人而言,我认为这可能是过度杀戮,不是很Python,但你可以这样做:
基本上,元类重新定义
__call__
,以确保在实例的init之后调用check_bar
。相关问题 更多 >
编程相关推荐