我喜欢 Python 的@property
装饰系统。我喜欢您可以在调用 aClassObect.attribute
时运行自定义代码。特别是在设置属性时验证数据。但是,我想要但找不到的一件事是一种在尝试设置不存在的属性时运行自定义代码的方法。例如,假设我有以下类(class):
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
的新属性。设置新属性时有什么方法可以运行特殊代码吗?我有能力提出错误,说“错误,这个属性不存在”之类的话。
最佳答案
详细说明 Elazar的答案,你会想要覆盖 __setattr__
魔术方法并检查它以查看该属性是否已经存在。如果不是,则引发异常。以下是您类(class)的情况:
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
在检查 x
是否为现有属性时将返回 False
,因此我的 __getattr__
不会不要让你重新创建它。如果您确实需要能够删除(和重新创建)特定属性,则需要更复杂的 __setattr__
实现(它可以在类中检查具有所需名称的属性,而不仅仅是依赖于 hasattr
)。
关于python - 类中未定义/未实现属性的 Python "catch all"方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16227657/