2017-09-16 223 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

我剛纔意識到我的企圖是多麼愚蠢。謝謝。 –