抽象属性(不是属性)? [英] Abstract attribute (not property)?
问题描述
定义抽象实例属性而不将其作为属性的最佳实践是什么?
What's the best practice to define an abstract instance attribute, but not as a property?
我想写一些类似的东西:
I would like to write something like:
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
c $ c> self.foo = foo 在 __ init __
中。)
Properties are handy, but for simple attribute requiring no computation they are an overkill. This is especially important for abstract classes which will be subclassed and implemented by the user (I don't want to force someone to use @property
when he just could have written self.foo = foo
in the __init__
).
<一个href = https://stackoverflow.com/questions/2736255/abstract-attributes-in-python> Python中的抽象属性问题建议使用 @property作为唯一答案 code>和
@abstractmethod
:它不能回答我的问题。
Abstract attributes in Python question proposes as only answer to use @property
and @abstractmethod
: it doesn't answer my question.
通过 AbstractAttribute的抽象类属性
可能是正确的方法,但是我不确定。
The ActiveState recipe for an abstract class attribute via AbstractAttribute
may be the right way, but I am not sure. It also only works with class attributes and not instance attributes.
推荐答案
如果您真的想强制子类定义给定的属性,那么它也仅适用于类属性,而不适用于实例属性。 ,您可以使用元类。就我个人而言,我认为这可能是矫kill过正,并且不是很pythonic,但您可以执行以下操作:
If you really want to enforce that a subclass define a given attribute, you can use metaclass. Personally, I think it may be overkill and not very pythonic, but you could do something like this:
class AbstractFooMeta(type):
def __call__(cls, *args, **kwargs):
"""Called when you call Foo(*args, **kwargs) """
obj = type.__call__(cls, *args, **kwargs)
obj.check_bar()
return obj
class AbstractFoo(object):
__metaclass__ = AbstractFooMeta
bar = None
def check_bar(self):
if self.bar is None:
raise NotImplementedError('Subclasses must define bar')
class GoodFoo(AbstractFoo):
def __init__(self):
self.bar = 3
class BadFoo(AbstractFoo):
def __init__(self):
pass
元类重新定义 __ call __
以确保在实例初始化后调用 check_bar
。
Basically the meta class redefine __call__
to make sure check_bar
is called after the init on an instance.
GoodFoo() # ok
BadFoo () # yield NotImplementedError
这篇关于抽象属性(不是属性)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!