getitem metodu, Python'da diziler ve haritalar için bir protokol parçası olarak eklenmiştir. Bu sihirli metot, standart koleksiyonların (list, tuple, dict vb.) indeks, anahtar ve dilimle erişimini sağlar. Kullanıcı sınıflarında bu metot, nesnelerin "koleksiyonlar gibi" davranmasına olanak tanır.
getitem uygulanmadığında, kullanıcı sınıfı indeksleme ve for döngüsü ile gezinmeyi desteklemez. Sadece basit indeksler için bir uygulama yapılması, dilimleme (slice) işlemlerinin tam anlamıyla çalışmasını engeller ve indeks çeşitlerinin göz ardı edilmesi hatalara yol açar.
Hem indeksler hem de slice türündeki nesneler için getitem uygulamak, işlemlerinde bunları ayırmayı sağlar. Bu, kullanıcı nesnelerinin Python'un standart yapılarında kullanılmasını olanak tanır (örneğin, dilimleme desteklemek için your_obj[1:5]).
Kod örneği:
class MyRange: def __init__(self, n): self.n = n def __getitem__(self, item): if isinstance(item, int): # Bireysel indeks if 0 <= item < self.n: return item * 2 raise IndexError('indeks aralık dışı') elif isinstance(item, slice): # Dilim return [self[i] for i in range(*item.indices(self.n))] else: raise TypeError('Geçersiz argüman türü: {}'.format(type(item))) mr = MyRange(10) print(mr[3]) # 6 print(mr[2:5]) # [4, 6, 8]
Anahtar özellikler:
Sadece getitem uygulayarak indeks üzerinden değer atama yapılabilir mi?
Hayır. Atama desteği (your_obj[i] = value) için setitem uygulamak gerekir. getitem sadece okumak için sorumludur.
getitem dilim üzerinde her zaman liste döndürmek zorunda mı, list gibi?
Hayır. Temel olan, sınıfın anlamını dikkate alarak "sıralı bir nesne" döndürmektir (aynı türü veya örneğin, tuple döndürebilirsiniz). Önemli olan, bu durumun bağlamında anlamlı olmasıdır.
Neden bazen TypeError: 'MyClass' object is not subscriptable hatasıyla karşılaşıyoruz?
Bu hata mesajı, my_obj[0] çalıştırmaya çalıştığınızda ve sınıf getitem'i uygulamadığında ortaya çıkar. Sınıfın subscriptable ([]) desteklemesi için bu metod zorunludur.
getitem sadece int için uygulanmış, slice unutulmuş. Herhangi bir my_obj[2:5] denemesi TypeError ile sonuçlanır ve tüm koleksiyon işleme algoritması çökebilir.
Artılar:
Eksiler:
getitem ayrı slice ve int işlemesi ile uygulanmış. Dilimler ve indeksler çalışıyor, list(), map(), yineleme yöntemleri ek bir çaba gerektirmeden destekleniyor.
Artılar:
Eksiler: