16

喜欢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,它是 class 的一个实例C,并且我调用myObject.x = 42,它将运行适当的 setter,这对于验证数据非常有用。但这并不能阻止某人调用myOjbect.b = 47,它会愉快地创建一个名为 的新属性b。设置新属性时有什么方法可以运行特殊代码吗?我有能力提出错误,比如“错误,这个属性不存在”。

4

2 回答 2

14

为了详细说明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__,由于删除器,我上面显示的方法不能完全与您当前的属性完美配合。如果你 delete myObj.x,如果你稍后尝试访问,getter 将引发异常x。这意味着在检查是否是现有属性时hasattr将返回,因此我不会让您重新创建它。如果您确实需要能够删除(并重新创建)特定属性,则需要更复杂的实现(它可以在类中检查具有所需名称的属性,而不仅仅是依赖于)。Falsex__getattr____setattr__hasattr

于 2013-04-26T02:56:25.210 回答
11

覆盖__getattr____setattr__

于 2013-04-26T02:13:05.440 回答