2017-04-26 2 views
6

Ich habe die meiste Dokumentation von __getitem__ in den Python-Dokumenten und auch in stackoverflow durchlaufen, so dass dies keine doppelte Frage ist. Aber ich bin immer noch nicht in der Lage, die Bedeutung davon zu erfassen.Understanding __getitem__ Methode

Also alles, was ich verstehen kann ist, dass __getitem__ verwendet wird, um Anrufe wie self[key] zu implementieren. Aber was nützt es?

Lets sagen, dass ich eine Python-Klasse haben auf diese Weise definiert:

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"]) 

Dies gibt die Ergebnisse als erwartet. Aber warum zuerst __getitem__ verwenden? Ich habe auch gehört, dass Python intern __getitem__ aufruft. Aber warum macht es das?

Kann mir bitte jemand das genauer erklären?

+0

Dies könnte für ein Beispiel von Interesse sein: [Wie ordnungsgemäß Unterklasse dict und override __getitem__ & __setitem__ ] (http://stackoverflow.com/questions/2390827/how-to-properly-subclass-dict-and-override-getitem-setitem) – roganjosh

+0

Die '__getitem__' Verwendung in Ihrem Beispiel macht nicht viel Sinn, aber stell dir vor, du brauchst t o schreibe eine benutzerdefinierte Liste oder Dictionary-ähnliche Klasse, die mit existierendem Code arbeiten muss, der '[]' verwendet. Das ist eine Situation, in der "__getitem__" nützlich ist. –

Antwort

7

Cong Ma macht einen guten Job zu erklären, was `getitem 'für verwendet wird - aber ich möchte Ihnen eine geben Beispiel, das nützlich sein könnte. Stellen Sie sich eine Klasse vor, die ein Gebäude modelliert. Innerhalb der Daten für das Gebäude es eine Reihe von Attributen enthält, einschließlich einer Beschreibung der Unternehmen, die jedes Stockwerk besetzen:

Ohne __getitem__ verwenden wir würden eine Klasse wie dieses:

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

Wir aber __getitem__ nutzen könnten (und sein Gegenstück __setitem__), um die Verwendung der Building-Klasse 'netter' zu machen.

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

Ob Sie __setitem__ wie dies hängt wirklich davon ab, wie Sie mit abstrakten Daten planen - in diesem Fall haben wir uns entschlossen, ein Gebäude als Container Etagen zu behandeln (und man könnte auch einen Iterator für das Gebäude implementieren und vielleicht sogar die Fähigkeit, Slice - dh mehr als eine Etage Daten auf einmal zu bekommen - es hängt davon ab, was Sie brauchen.

3

Die [] Syntax zum Abrufen von Element nach Schlüssel oder Index ist nur Syntax Zucker.

Wenn Sie a[i] bewerten, ruft Python a.__getitem__(i) (oder type(a).__getitem__(a, i), aber diese Unterscheidung ist über Vererbungsmodelle und ist hier nicht wichtig). Auch wenn die Klasse a diese Methode nicht explizit definiert, wird sie normalerweise von einer Vorgängerklasse geerbt.

das All (Python 2.7) spezielle Methodennamen und ihre Semantik hier aufgeführt sind: https://docs.python.org/2.7/reference/datamodel.html#special-method-names