getitem__ yöntemini anlama

Python dokümanlarındaki ve stackoverflow'daki __getitem__ dokümantasyonunun çoğunu inceledim, bu yüzden bu tekrarlanan bir soru değil. Ama hala anlamını kavrayabilmiş değilim.

Yani tek anlayabildiğim __getitem__ self[key] gibi çağrıları uygulamak için kullanılıyor. Ama bunun kullanımı nedir?

Diyelim ki bu şekilde tanımlanmış bir python sınıfım var:

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

Bu, sonuçları beklendiği gibi döndürür. Ama neden ilk etapta __getitem__ kullanılıyor? Pythonungetitem`i dahili olarak çağırdığını da duydum. Ama bunu neden yapıyor?

Lütfen birisi bunu daha ayrıntılı açıklayabilir mi?

Çözüm

Cong Ma, __getitem__in ne için kullanıldığını açıklamakta iyi bir iş çıkarıyor - ancak ben size yararlı olabilecek bir örnek vermek istiyorum. Bir binayı modelleyen bir sınıf düşünün. Binanın verileri içinde, her bir katı işgal eden şirketlerin açıklamaları da dahil olmak üzere bir dizi öznitelik içerir:

getitem__` kullanmasaydık şöyle bir sınıfımız olurdu:

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

Bununla birlikte, Building sınıfının kullanımını 'daha güzel' hale getirmek için __getitem__ (ve onun muadili __setitem__) kullanabiliriz.

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

Bu şekilde __setitem__ kullanıp kullanmayacağınız gerçekten verilerinizi nasıl soyutlamayı planladığınıza bağlıdır - bu durumda bir binayı katların bir konteyneri olarak ele almaya karar verdik (ve ayrıca Bina için bir yineleyici uygulayabilir ve hatta belki dilimleme yeteneği - yani bir seferde birden fazla katın verilerini alabilirsiniz - neye ihtiyacınız olduğuna bağlıdır.

Yorumlar (6)

Anahtar veya dizine göre öğe almak için [] sözdizimi sadece sözdizimi şekeridir.

a[i]öğesini değerlendirdiğinizde Pythona.getitem(i)(veyatype(a).getitem(a, i)) öğesini çağırır, ancak bu ayrım kalıtım modelleriyle ilgilidir ve burada önemli değildir). a sınıfı bu yöntemi açıkça tanımlamasa bile, genellikle bir ata sınıftan miras alınır.

Tüm (Python 2.7) özel yöntem adları ve anlamları burada listelenmiştir: https://docs.python.org/2.7/reference/datamodel.html#special-method-names

Yorumlar (0)

Sihirli yöntem __getitem__ temel olarak liste öğelerine, sözlük girdilerine, dizi öğelerine vb. erişmek için kullanılır. Örnek niteliklerinin hızlı bir şekilde aranması için çok kullanışlıdır.

Burada bunu, 'name', 'age' ve 'dob' (doğum tarihi) ile örneklenebilen örnek bir Person sınıfı ile gösteriyorum. getitem__` yöntemi, ad veya soyad, gün, ay veya dob yılı gibi indekslenmiş örnek niteliklerine erişilebilecek şekilde yazılmıştır.

import copy

# Constants that can be used to index date of birth's Date-Month-Year
D = 0; M = 1; Y = -1

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

    def __getitem__(self, indx):
        print ("Calling __getitem__")
        p = copy.copy(self)

        p.name = p.name.split(" ")[indx]
        p.dob = p.dob[indx] # or, p.dob = p.dob.__getitem__(indx)
        return p

Bir kullanıcı girdisinin aşağıdaki gibi olduğunu varsayalım:

p = Person(name = 'Jonab Gutu', age = 20, dob=(1, 1, 1999))

Kullanıcı, __getitem__ metodu yardımıyla indekslenmiş özniteliklere erişebilir. ör,

print p[0].name # print first (or last) name
print p[Y].dob  # print (Date or Month or ) Year of the 'date of birth'
Yorumlar (0)