Python 巨蟒;“一网打尽”;类中未定义/未实现属性的方法
我喜欢Python的Python 巨蟒;“一网打尽”;类中未定义/未实现属性的方法,python,Python,我喜欢Python的@属性装饰系统。我喜欢在调用aClassObect.attribute时可以运行自定义代码。特别是在设置属性时验证数据。然而,有一件事我想要,但我找不到,那就是在试图设置一个不存在的属性时运行自定义代码的方法。例如,假设我有以下课程: class C(object): def __init__(self): self._x = None @property def x(self): """I'm the 'x' pro
@属性
装饰系统。我喜欢在调用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
的新属性。在设置新属性时,是否有办法运行特殊代码?我希望能够引发错误,比如说“error,this attribute不存在”。覆盖\uuuu getattr\uuuuu
和\uuu setattr\uuuuu要详细说明的答案,您需要覆盖magic方法并检查它是否已经存在。如果没有,则引发异常。以下是您的班级的情况:
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)
如果要处理对不存在的属性的请求,也可以覆盖\uuuuu getattr\uuuuuu
或\uuuuu getattribute\uuuuuuuu
,但对于您描述的特定问题,这可能不是必需的
请注意,由于deleter,我上面展示的\uuuuu setattr\uuuu
方法不能很好地处理当前属性。如果您删除myObj.x
,如果您稍后尝试访问x
,则随后getter将引发异常。这意味着当检查x
是否为现有属性时,hasattr
将返回False
,因此my\uuuu getattr\uuuu
不允许您重新创建它。如果您确实需要能够删除(并重新创建)特定属性,则需要更复杂的\uuu setattr\uuuu
实现(它可以在类中检查具有所需名称的属性,而不仅仅依赖hasattr
)。我有一个类用作数据库的API。每个实例代表一个条目。修改对象的属性(表示数据库中的字段)后,可以调用object.save()
来更新数据库。我希望引发一个错误,而不是悄悄地删除字段,因为它们实际上不存在于DB中。哦,等等,我很确定这会起作用,但有一个问题:这个限制适用于所有地方,包括在初始化值时的构造函数中。我刚试过,它在构造函数中用AttributeError
阻止了我。有办法吗?@J-bob:啊,是的。如果要绕过检查,必须在设置属性的任何地方显式调用super(C,self)。\uuuu setattr\uuuuuu(“\ux”,None)
。我找到了一个很好的解决方案。在我的文件顶部,Iimport inspect
。然后我将您的行,if not hasattr(self,name):
替换为if not hasattr(self,name)并检查.stack()[1][3]!='__初始化:
inspect.stack
让我们检查调用堆栈,以便此代码检查调用它的方法的名称。如果调用方法是\uuuu init\uuuu
,则允许创建属性。否则会引发错误。我建议修改您的答案以显示这一点。