2017-09-16 225 views
-1

在将其标记为重复项之前,我之前知道此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. 

我试图保持这种尽可能的干燥,因为我有子类_Base很多。

+1

你不是在课堂上设置它,而是将它设置在对象上。描述符不会像那样工作。 –

回答

2

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)。

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的对象仍然存在并结合,但表现为如果当一个标记被设置为假不存在的属性。

+0

我刚才意识到我的企图是多么愚蠢。谢谢。 –