2016-05-31 57 views
0

我有一個繼承自OrderedDict的類,但我不知道這是否是正確的方式來完成我所需要的。在Python上掩蓋函數的方法對象

我希望該課程具有javascript'。'的決鬥方法。象obj.<property>這樣的符號,我也想讓用戶能夠訪問像obj['myproperty']這樣的類屬性,但是我隱藏了所有的key()和get()函數。繼承模型提供了很好的功能,但它使用其他不真正需要的方法混淆了對象。

有沒有可能得到字典的行爲沒有所有其他功能?

爲了便於討論,我們假設我的課是這樣的:

from six.moves.urllib import request 
import json 
class MyClass(OrderedDict): 
    def __init__(self, url): 
     super(MyClass, self).__init__(url=url) 
     self._url = url 
     self.init() 
    def init(self): 
     # call the url and load the json 
     req = request.Request(self._url) 
     res = json.loads(request.urlopen(req).read()) 
     for k,v in res.items(): 
      setattr(self, k, v) 
     self.update(res) 
     self.__dict__.update(res) 

if __name__ == "__main__": 
    url = "https://sampleserver5.arcgisonline.com/ArcGIS/rest/services?f=json" 
    props = MyClass(url=url) 
    props.currentVersion 

是否有另一種方式來處理這個難題呢?

感謝

+0

@LutzHorn我看到這篇文章,我覺得它是不同的。 –

+0

@LutzHorn - 我知道,但我覺得這應該是更多的應該字典用於繼承模仿括號方法和JS點符號比'私人'。我認爲你很快就會反彈:) –

+1

那麼也許不要使用繼承,而是一個門面。 – 2016-05-31 14:02:43

回答

3

如果你想要的是x['a']以相同的方式工作作爲x.a沒有字典的任何其他功能,那麼就不要從dictOrderedDict繼承,而不是僅僅前進鍵/操作指數之(__getitem__, __setitem__ and __delitem__)至attribute operations

class MyClass(object): 
    def __getitem__(self,key): 
     try: #change the error to a KeyError if the attribute doesn't exist 
      return getattr(self,key) 
     except AttributeError: 
      pass 
     raise KeyError(key) 

    def __setitem__(self,key,value): 
     setattr(self,key,value) 
    def __delitem__(self,key): 
     delattr(self,key) 

作爲額外的獎勵,因爲這些特殊的方法不檢查實例變量,方法名,如果你使用相同的名字它不會破壞:

x = MyClass() 
x['__getitem__'] = 1 
print(x.__getitem__) #still works 
print(x["__getattr__"]) #still works 

唯一的一次,它會破壞試圖使用__dict__,因爲這是實例變量的實際存儲時:

>>> x = MyClass() 
>>> x.a = 4 
>>> x.__dict__ = 1 #stops you right away 
Traceback (most recent call last): 
    File "<pyshell#36>", line 1, in <module> 
    x.__dict__ = 1 
TypeError: __dict__ must be set to a dictionary, not a 'int' 
>>> x.__dict__ = {} #this is legal but removes all the previously stored values! 
>>> x.a 
Traceback (most recent call last): 
    File "<pyshell#38>", line 1, in <module> 
    x.a 
AttributeError: 'MyClass' object has no attribute 'a' 

此外,您仍然可以通過使用vars()使用普通的字典方法:

x = MyClass() 
x.a = 4 
x['b'] = 6 
for k,v in vars(x).items(): 
    print((k,v)) 

#output 
('b', 6) 
('a', 4) 
>>> vars(x) 
{'b': 6, 'a': 4} 
+0

這個問題用Python 2.7和Python 3.x標記,所以你可能想問問OP是否真的需要這兩個。如果是這樣,我認爲你將不得不放棄'從...提高'。 –

+0

謝謝,改變它,所以我相信它現在兩個版本的作用是相同的。 –