如何在Python中定义将引发抽象代码框架NotImplementedError的惰性变量?
我想在类中定义一些常量,这些常量将在类实例(派生类)中定义-如果这些变量未在子类中重新定义,如何发出错误信号?我想在第一次阅读时提出如何在Python中定义将引发抽象代码框架NotImplementedError的惰性变量?,python,Python,我想在类中定义一些常量,这些常量将在类实例(派生类)中定义-如果这些变量未在子类中重新定义,如何发出错误信号?我想在第一次阅读时提出NotImplementedError class Parent(object): abstract_variable = ? # I want achieve same behavior for variable def abstract_function(self): raise NotImplementedError() cla
NotImplementedError
class Parent(object):
abstract_variable = ?
# I want achieve same behavior for variable
def abstract_function(self):
raise NotImplementedError()
class Child(Parent):
def __init__():
# should throw NotImplementedError() on read
print self.abstract_variable
可以用一行来做吗
abstract_variable = ?
请看他的答案,他提供了一个更好的答案
将该函数用作装饰器
class Parent(object):
@property
def abstract_variable(self):
raise NotImplementedError()
获取
实例.abstract_变量
将抛出一个NotImplementedError
首先,最清楚的是不要在父类中执行任何操作。
然后在读取时,您只会得到一个属性错误:
AttributeError: Child instance has no attribute 'abstract_variable'
或者在父类中,您可以有一个属性
,该属性会引发未实现错误
,并在每个子类中使用带有getter和setter的属性
覆盖它;或者在子类中,在类主体中将值设置为None
但是,如果要引发
未实现错误
,则可以创建非数据描述符(即,不带\uuuuuu集
,属性始终具有\uuu集
)。这允许您在子类中设置值
最直接的方法是
class abstract_attribute(object):
def __get__(self, obj, type):
raise NotImplementedError("This attribute was not set in a subclass")
你用起来就像
class Parent(object):
variable = abstract_attribute()
class Child(Parent):
def __init__(self):
try:
print(self.variable)
except Exception as e:
print("Got error %s" % e)
self.variable = 42
print(self.variable)
Child()
哪个输出
Got error This attribute was not set in a subclass
42
属性
无法像使用我的抽象_属性
那样轻松设置值
但是,等等,我们可以让它更神奇:描述符可以找出访问它的属性:
class abstract_attribute(object):
def __get__(self, obj, type):
# Now we will iterate over the names on the class,
# and all its superclasses, and try to find the attribute
# name for this descriptor
# traverse the parents in the method resolution order
for cls in type.__mro__:
# for each cls thus, see what attributes they set
for name, value in cls.__dict__.items():
# we found ourselves here
if value is self:
# if the property gets accessed as Child.variable,
# obj will be done. For this case
# If accessed as a_child.variable, the class Child is
# in the type, and a_child in the obj.
this_obj = obj if obj else type
raise NotImplementedError(
"%r does not have the attribute %r "
"(abstract from class %r)" %
(this_obj, name, cls.__name__))
# we did not find a match, should be rare, but prepare for it
raise NotImplementedError(
"%s does not set the abstract attribute <unknown>", type.__name__)
和Child.variable
给出
NotImplementedError: <class '__main__.Child'> does not have the
attribute 'variable' (abstract from class 'Parent')
NotImplementedError:没有
属性“variable”(从类“Parent”抽象)
看看。您希望子类用类变量还是实例变量覆盖父类?也就是说,如果它做对了,孩子会是什么样子?看起来很有希望,我很快就会测试。看来这正是我们需要的。非常感谢您的回答,我将在第一次测试后接受这个问题。特别好的是多态性与mro与我经常使用太多。
NotImplementedError: <class '__main__.Child'> does not have the
attribute 'variable' (abstract from class 'Parent')