我喜欢 Python的@property
装饰系统。我喜欢您在致电aClassObect.attribute
时可以运行自定义代码。特别是在设置属性时验证数据。但是,我想要的一件事,但我找不到,是一种在尝试设置不存在的属性时运行自定义代码的方法。例如,假设我有以下课程:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
现在,如果我有myObj
,这是类C
的一个实例,并且我调用myObject.x = 42
,它将运行相应的setter,这对于验证数据非常有用。但这并不能阻止某人调用myOjbect.b = 47
,并且会很乐意创建一个名为b
的新属性。设置新属性时是否有某种方法可以运行特殊代码?我有能力提出错误,说“错误,这个属性不存在”。
答案 0 :(得分:9)
要详细说明Elazar的答案,您需要覆盖__setattr__
魔术方法,并检查其中是否已存在该属性。如果没有,请提出异常。以下是您班级的样子:
def __setattr__(self, name, value):
if not hasattr(self, name): # would this create a new attribute?
raise AttributeError("Creating new attributes is not allowed!")
super(C, self).__setattr__(name, value)
如果您想处理对不存在的属性的请求,也可以覆盖__getattr__
或__getattribute__
,但对于您所描述的特定问题,这可能不是必需的。
请注意,由于删除操作,我上面显示的__setattr__
方法不能完全与您当前的属性完美匹配。如果您删除myObj.x
,之后如果您稍后尝试访问x
,则getter会引发异常。这意味着hasattr
在检查False
是否为现有属性时会返回x
,因此我的__getattr__
将不允许您重新创建它。如果您确实需要能够删除(并重新创建)特定属性,则需要更复杂的__setattr__
实现(它可以在类中检查具有所需名称的属性,而不仅仅是依赖于{ {1}})。
答案 1 :(得分:8)
覆盖__getattr__
和__setattr__
。