2017-04-26 69 views
6

我已經經歷了Python文檔中的大多數__getitem__的文檔,並且也在stackoverflow中,因此這不是重複的問題。但我仍然無法理解它的意義。瞭解__getitem__方法

所以我能理解的是__getitem__被用來實現像self[key]這樣的調用。但是它有什麼用處?

可以說我有這樣定義一個Python類:

class Person: 
    def __init__(self,name,age): 
     self.name = name 
     self.age = age 

    def __getitem__(self,key): 
     print ("Inside `__getitem__` method!") 
     return getattr(self,key) 

p = Person("Subhayan",32) 
print (p["age"]) 

這將返回的結果符合預期。但爲什麼首先使用__getitem__?我也聽說Python在內部調用__getitem__。但它爲什麼這樣做呢?

有人可以請詳細解釋一下嗎?

+0

這可能是一個例子使用的興趣:[如何正確地繼承dict並覆蓋__getitem__&__setitem__ ](http://stackoverflow.com/questions/2390827/how-to-properly-subclass-dict-and-override-getitem-setitem) – roganjosh

+0

在你的例子中使用'__getitem__'沒有多大意義,但想象你需要t o編寫一個自定義列表或字典類的類,它必須與使用'[]'的現有代碼一起工作。這是'__getitem__'有用的情況。 –

回答

7

驄馬做了解釋什麼`的GetItem'用於一個良好的工作 - 但我想給你一個可能有用的例子。 想象一下建築物的建模。用於建築,它包括一些屬性,其中包括佔據每層公司的描述,數據中:

不使用__getitem__,我們將有一個這樣的類:

class Building(object): 
    def __init__(self, floors): 
     self._floors = [None]*floors 
    def occupy(self, floor_number, data): 
      self._floors[floor_number] = data 
    def get_floor_data(self, floor_number): 
      return self._floors[floor_number] 

building1 = Building(4) # Construct a building with 4 floors 
building1.occupy(0, 'Reception') 
building1.occupy(1, 'ABC Corp') 
building1.occupy(2, 'DEF Inc') 
print(building1.get_floor_data(2)) 

我們可以使用,無論__getitem__ (和它的對應__setitem__)使建築類的使用更好。

class Building(object): 
    def __init__(self, floors): 
     self._floors = [None]*floors 
    def __setitem__(self, floor_number, data): 
      self._floors[floor_number] = data 
    def __getitem__(self, floor_number): 
      return self._floors[floor_number] 

building1 = Building(4) # Construct a building with 4 floors 
building1[0] = 'Reception' 
building1[1] = 'ABC Corp' 
building1[2] = 'DEF Inc' 
print(building1[2]) 

無論您使用__setitem__喜歡這真的取決於你打算如何抽象的數據 - 在這種情況下,我們決定把建築物作爲地板的容器(你也可以實現對建築物的迭代器,甚至可能分片 - 即一次獲取多個樓層的數據 - 這取決於你需要什麼。

3

[]通過鍵或索引獲取項目的語法只是語法糖。

當你評估a[i] Python調用a.__getitem__(i)(或type(a).__getitem__(a, i),但這種區別是關於繼承模型,這裏不重要)。即使類a未明確定義此方法,它通常從祖先類繼承。

所有(Python 2.7版)的特殊方法的名字和它們的語義在這裏列出:https://docs.python.org/2.7/reference/datamodel.html#special-method-names