2017-04-26 15 views
6

Tôi đã trải qua hầu hết tài liệu của __getitem__ trong tài liệu Python và cũng trong stackoverflow vì vậy đây không phải là câu hỏi trùng lặp. Nhưng tôi vẫn không thể hiểu ý nghĩa của nó.Tìm hiểu phương thức __getitem__

Vì vậy, tất cả những gì tôi có thể hiểu là __getitem__ được sử dụng để triển khai các cuộc gọi như self[key]. Nhưng việc sử dụng nó là gì?

phép nói rằng tôi có một lớp python định nghĩa theo cách này:

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

này trả về kết quả như mong đợi. Nhưng tại sao lại sử dụng __getitem__ ngay từ đầu? Tôi cũng đã nghe nói rằng Python gọi __getitem__ nội bộ. Nhưng tại sao nó làm điều đó?

Ai đó có thể giải thích điều này chi tiết hơn không?

+0

Điều này có thể quan tâm đến một ví dụ sử dụng: [Làm thế nào để đúng phân lớp dict và ghi đè __getitem__ & __setitem__ ] (http://stackoverflow.com/questions/2390827/how-to-properly-subclass-dict-and-override-getitem-setitem) – roganjosh

+0

Việc sử dụng '__getitem__' trong ví dụ của bạn không có nhiều ý nghĩa, nhưng hãy tưởng tượng rằng bạn cần t o viết một danh sách tùy chỉnh hoặc từ điển giống như từ điển, mà phải làm việc với mã hiện có sử dụng '[]'. Đó là một tình huống mà '__getitem__' hữu ích. –

Trả lời

7

Cong Ma làm một công việc tốt trong việc giải thích những gì `GetItem 'được sử dụng cho - nhưng tôi muốn cung cấp cho bạn một ví dụ có thể hữu ích. Hãy tưởng tượng một lớp mô hình một tòa nhà. Trong dữ liệu cho việc xây dựng nó bao gồm một số thuộc tính, bao gồm mô tả trong những công ty mà chiếm mỗi sàn:

Nếu không sử dụng __getitem__ chúng ta sẽ có một lớp học như thế này:

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

Chúng tôi tuy nhiên có thể sử dụng __getitem__ (và nó là đối tác __setitem__) để làm cho việc sử dụng của lớp Xây dựng 'đẹp hơn'.

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

Cho dù bạn sử dụng __setitem__ như thế này thực sự phụ thuộc vào cách bạn có kế hoạch để trừu tượng dữ liệu của bạn - trong trường hợp này, chúng tôi đã quyết định để điều trị một tòa nhà như một container tầng (và bạn cũng có thể thực hiện một iterator cho tòa nhà và thậm chí có khả năng cắt - tức là có được nhiều hơn một tầng dữ liệu tại một thời điểm - nó phụ thuộc vào những gì bạn cần

3

Cú pháp [] để nhận mục theo khóa hoặc chỉ mục chỉ là đường cú pháp.

Khi bạn đánh giá a[i] Gọi Python a.__getitem__(i) (hoặc type(a).__getitem__(a, i), nhưng sự khác biệt này là về mô hình kế thừa và không quan trọng ở đây). Ngay cả khi lớp học của a có thể không xác định rõ ràng phương pháp này, nó thường được thừa kế từ một lớp tổ tiên.

Tất cả các (Python 2.7) tên phương pháp đặc biệt và ngữ nghĩa của họ được liệt kê ở đây: https://docs.python.org/2.7/reference/datamodel.html#special-method-names

Các vấn đề liên quan