2017-04-20 109 views
0

我認爲用一個簡單的例子來解釋我試圖實現的東西更容易。請看下面的代碼:方法鏈接和訪問變量

class Person(object): 
    def __init__(self): 
     self._age = None 
     self._gender = None 

    def age(self, value): 
     self._age = value 
     return self 

    def gender(self, value): 
     self._gender = value 
     return self 


p = Person().age(10).gender("male") 

assert p.age == 10 
assert p.gender == "male" 

顯然因爲屬性指的是方法,而不是變量斷言失敗。 我試圖搞亂__getattribute__方法,以便它解決「年齡」爲「_age」,但我似乎無法找到一種方式,兩種情況下工作,我不完全相信,它可能在所有,但Python已之前感到驚訝。

+0

如果你真的想用數據隱藏,這裏是一個[示例](http://stackoverflow.com/questions/6304040 /現實世界中的示例中關於如何使用屬性功能在python/42300481#42300481)應該讓你開始的屬性。 – Mike

回答

2

簡答:不。你將遇到問題,每個使用/讀取你的代碼的人都會遇到問題,而且你花在實現它上的時間也不值得。


長答案:如果您絕對必須,您可以創建一個類,在調用時設置該屬性的值,否則模仿該值的行爲。要做到這一點,您必須覆蓋全部magic methods,即使如此,print(type(p.age))之類的東西也不會產生<class 'int'>的預期輸出。

這裏有讓你開始一個片斷(只實施了__eq__法):

class CallableAttribute: 
    def __init__(self, owner, name): 
     self.owner= owner 
     self.name= name 

     setattr(owner, name, self) 
     self(None) 

    def __call__(self, value): 
     setattr(self.owner, '_'+self.name, value) 
     return self.owner 

    @property 
    def _value(self): 
     return getattr(self.owner, '_'+self.name) 

    def __eq__(self, other): 
     return self._value==other 

class Person(object): 
    def __init__(self): 
     CallableAttribute(self, 'age') 
     CallableAttribute(self, 'gender') 
+0

你可能是對的,我應該重新考慮設計選擇。一個簡短的後續問題:如果我添加:assert p.age * 2 == 20,我得到TypeError:不支持的操作數類型(s)*:'instance'和'int' - 有沒有辦法繞過這個一個優雅的方式? –

+0

@MattImmer是的,你只需重寫['__mul__'](https://docs.python.org/3/reference/datamodel.html#object.__mul__)函數。 –

+0

謝謝!我會注意到這樣做是可能的但不好的做法,可能會考慮替代設計。 –