在此之前被标记为重复之前,我之前知道这个question has been answered,但那里提供的解决方案似乎并不适用于我的案例。我试图以编程方式设置类属性。我知道我可以使用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
有什么方法可以解决这个问题吗?
编辑:
我觉得我可能遗漏了太多,所以这就是我实际想要达到的目标。我有一个类,其变量名为config
,其中包含要设置为属性的配置值。该类应该被子类化以实现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.
我试图尽可能保持DRY,因为我必须经常继承_Base
。
答案 0 :(得分:3)
property
个对象是descriptors,只有在类或元类上定义时才会调用描述符。你不能直接把它们放在一个实例上;类的__getattribute__
实现只是不调用所需的绑定行为。
您需要将属性放在类上,而不是放在每个实例上:
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
这样该属性应该不存在&#39;)。
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时,其行为就像该属性不存在一样。