Class 属性 返回 属性 对象

Class property returning property object

在这被标记为重复之前,我以前就知道这个 question has been answered,但那里提供的解决方案似乎不适用于我的情况。我正在尝试以编程方式设置 class 属性。我知道我可以为此使用 property,所以我考虑过这样做:

class Foo:
    def __init__(self, x):
        self._x = x
        def getx(): return self._x
        def setx(y): self._x = y
        self.x = property(fget=getx, fset=setx)

但是,当我 运行 以交互方式进行此操作时,我得到:

>>> f = Foo(42)
>>> f.x
<property object at 0x0000000>
>>> f._x
42
>>> f.x = 1
>>> f.x
1

有什么办法可以解决吗?

编辑:

我觉得我可能遗漏了太多,所以这就是我真正想要达到的目标。我有一个 class 和一个名为 config 的 class 变量,它包含要设置为属性的配置值。 class 应该被子classed 以实现 config 变量:

class _Base:
    config = ()

    def __init__(self, obj, **kwargs):
        self._obj = obj()
        for kwarg in kwargs:
            # Whatever magic happens here to make these properties

# Sample implementation
class Bar(_Base):
     config = (
         "x",
         "y"
     )

     def __init__(self, obj, x, y):
         super().__init__(obj, x=x, y=y)

现在允许操作:

>>> b = Bar(x=3, y=4)
>>> b.x
3
>>> # Etc.

我尽量保持干燥,因为我必须经常使用 subclass _Base

property 对象是 descriptors,描述符仅在 class 或 metaclass 上定义时调用。您不能将它们直接放在实例上; __getattribute__ classes 的实现根本不调用所需的绑定行为。

您需要将 属性 放在 class 上,而不是在每个实例上:

class Foo:
    def __init__(self, x):
        self._x = x

    @property
    def x(self): return self._x

    @x.setter
    def x(self, y): self._x = y

如果你必须有一个只适用于某些情况的 属性,你将不得不改变你的 getter 和 setter 方法来改变行为(比如引发 AttributeError 因为当实例的状态是属性应该 'not exist').

class Bar:
    def __init__(self, has_x_attribute=False):
        self._has_x_attribute = has_x_attribute
        self._x = None

    @property
    def x(self):
        if not self._has_x_attribute:
            raise AttributeError('x')
        return self._x

    @x.setter
    def x(self, y):
        if not self._has_x_attribute:
            raise AttributeError('x')
        self._x = y

property 对象仍然存在并被绑定,但当标志设置为 false 时,其行为就好像该属性不存在一样。