在 python 中使用 属性() 结构

Usage of property() contruct in python

我在 python 中尝试使用带有验证的小型数据库管理器,但我遇到了这个问题:

如果我这样使用@属性:

class Attribute (object):
    def __init__ (self, value=None):
        self._value = value
    @property
    def value (self):
        return self._value
    @value.setter
    def value (self, value):
        if isinstance(value,int):
            self._value = value
        else:
            self._value = None

class A (object):
    def __init__ (self):
        self.a = Attribute()

ia = A()

然后我可以将验证值访问为 ia.a.value 并将其设置为验证为 intia.a.value=<some int>。但我希望它可以被 ia.a 访问(没有 value

我已经为以下(由 Sublime Text 2 自动生成)代码尝试了我能想到的大部分变体:

def attribute ():
    def fget (self):
        return self._value
    def fset (self, value):
        if isinstance(value,int):
            self._value = value
        else:
            self._value = None
    return locals()

class A (object):
    def __init__ (self):
        self.a = property(**attribute())

ia = A()

当我执行 print(type(ia.a)) 时,它会输出类似“<property object at 0x7ffa84a8a7e0>”的内容,但是一旦我用 ia.a=3 更改值,它就会变成 int .事实上,setter 没有被调用,赋值和往常一样(例如,我可以将一个字符串赋给 属性)。

我想做的是一些动态 class 设置,方法是将参数传递给 attribute 函数,其中包含每个用户定义的 class 属性的名称,以便定义实例属性在该函数中使用 getattrsetattrdelattr

我该怎么做? parameter 构造函数的正确用法是什么?

问题是 属性 对象应该设置在 class 上(作为 class 属性),而不是实例上,这就是为什么 setter/getter 永远不会打电话给你 属性.

对于你的情况,你可以简单地做 -

class A:
    a = property(**attribute())