Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.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_Python 3.x_Properties_Metaprogramming - Fatal编程技术网

Python 类属性返回属性对象

Python 类属性返回属性对象,python,python-3.x,properties,metaprogramming,Python,Python 3.x,Properties,Metaprogramming,在这被标记为重复之前,我知道这一点,但这里提供的解决方案似乎不适用于我的案例。我正在尝试以编程方式设置类属性。我知道我可以使用属性,所以我考虑这样做: 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)

在这被标记为重复之前,我知道这一点,但这里提供的解决方案似乎不适用于我的案例。我正在尝试以编程方式设置类属性。我知道我可以使用
属性
,所以我考虑这样做:

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
现在可以进行操作:

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

我正在尽可能地保持这一点,因为我必须对
\u Base
进行大量的子类化。

属性
对象是对象,只有在类或元类上定义时才会调用描述符。你不能把它们直接放在一个实例上;类的
\uuu getattribute\uu
实现根本不调用所需的绑定行为

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

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


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

您不是在类上设置它,而是在对象上设置它。描述符不是那样工作的。我刚刚意识到我的尝试是多么愚蠢。谢谢
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
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