我想在类中定义一些常量,这些常量将在类实例(派生类)中定义——如果这个变量没有在子类中重新定义,如何发出错误信号?我想在第一次阅读时引发 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 = ?
最佳答案
首先,最清楚的是在父类中不做任何事情。 然后在阅读时你只会得到一个属性错误:
AttributeError: Child instance has no attribute 'abstract_variable'
或者在父类中你可以有一个 property
引发 NotImplementedError
并用 property
覆盖它每个子类中都有 getter 和 setter;或者在子类中将值设置为类主体中的 None
...
但是,如果您想引发 NotImplementedError
,您可以制作一个非数据 描述符(即 descriptor class 没有 __set__
,一个 property
总是有 __set__
)。这允许您在子类中设置值。
最直接的方法是
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
property
无法像使用我的 abstract_attribute
那样轻松地设置值。
但是等等,我们可以让它更神奇一点:描述符可以找出它是从哪个属性访问的:
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__)
使用此代码,访问 self.variable
会引发异常并显示一条非常有用的消息:
NotImplementedError: <__main__.Child object at 0x7f7c7a5dd860> does not
have the attribute 'variable' (abstract from class 'Parent')
和Child.variable
给出
NotImplementedError: <class '__main__.Child'> does not have the
attribute 'variable' (abstract from class 'Parent')
关于python - 如何在 Python 中定义惰性变量,这将引发抽象代码框架的 NotImplementedError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32536176/