Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 巨蟒;“一网打尽”;类中未定义/未实现属性的方法_Python - Fatal编程技术网

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

我喜欢Python的
@属性
装饰系统。我喜欢在调用
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)
。我找到了一个很好的解决方案。在我的文件顶部,I
import inspect
。然后我将您的行,
if not hasattr(self,name):
替换为
if not hasattr(self,name)并检查.stack()[1][3]!='__初始化:
inspect.stack
让我们检查调用堆栈,以便此代码检查调用它的方法的名称。如果调用方法是
\uuuu init\uuuu
,则允许创建属性。否则会引发错误。我建议修改您的答案以显示这一点。