Yanıtlar:
Temel olarak nesnenin __getitem__()
yöntemi uyguladığı anlamına gelir . Başka bir deyişle, "kapsayıcı" olan nesneleri, yani başka nesneleri içerdiklerini açıklar. Buna dizeler, listeler, tuples ve sözlükler dahildir.
[
... ]
indeksleme sözdizimi bir denir simge o matematiksel gösterime eşdeğer, çünkü kullanımları fiili simgeler olduğunu; Örneğin a[1]
matematikçilerin a₁ olarak yazacakları için Python . Yani "abone olunabilir", "abone olunabilir" anlamına gelir. Ki, Python açısından, bu uygulamaya sahip demektir __getitem__()
, çünkü a[1]
sadece sözdizimsel şeker a.__getitem__(1)
.
hasattr
iyi çalışması gerekir, ancak bir şeyler yapmanın Pitonik yolu değildir; Python uygulaması Duck Typing'i teşvik eder . Yani, bir alt simge kullanarak nesnenizden bir öğe almaya çalışmayı planlıyorsanız, devam edin ve yapın; Nesne abone edilemediğinden işe yaramayabileceğini düşünüyorsanız, try
ile bir blokta sarın except TypeError
.
Başımın üst kısmında, abone olunabilen tek yerleşik öğeler şunlardır:
string: "foobar"[3] == "b"
tuple: (1,2,3,4)[3] == 4
list: [1,2,3,4][3] == 4
dict: {"a":1, "b":2, "c":3}["c"] == 3
Ancak mipadi'nin cevabı doğrudur - uygulayan herhangi bir sınıf __getitem__
aboneliklidir
Komut dosyası yazılabilir nesne, kendisine yapılan işlemleri kaydeden bir nesnedir ve bunları yeniden oynatılabilen bir "komut dosyası" olarak depolayabilir.
Örneğin, bkz. Uygulama Komut Dosyası Çerçevesi
Şimdi, eğer Alistair ne istediğini bilmiyorsa ve gerçekten "abonelikli" nesneler demek isterse (başkaları tarafından düzenlendiği gibi), o zaman (mipadi'nin de cevapladığı gibi) bu doğru olanıdır:
Abone olabilen bir nesne, __getitem__
özel yöntemi (düşünme listeleri, sözlükler) uygulayan herhangi bir nesnedir .
Bilgi işlemdeki alt simge anlamı: "bir programın tek başına veya başkalarıyla birlikte bir dizinin öğelerinden birini belirtmek için kullanılan bir simge (zaman zaman alt simge olarak yazılır ancak uygulamada genellikle kullanılmaz)."
Şimdi, @ user2194711 tarafından verilen basit örnekte , ekleme öğesinin iki nedenden dolayı listenin bir parçası olamayacağını görebiliriz: -
1) Yönteme ekleme işlemini gerçekten çağırmıyoruz; çünkü onu ()
çağırması gerekiyor.
2) Hata, işlevin veya yöntemin abone edilemediğini gösterir; bir liste veya sıra gibi dizine eklenemedikleri anlamına gelir.
Şimdi şuna bakın: -
>>> var = "myString"
>>> def foo(): return 0
...
>>> var[3]
't'
>>> foo[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'function' object is not subscriptable
Bu, herhangi bir abonelik veya function
dizideki öğelerin sıralı olarak meydana geldiği anlamına gelir ; ve onların yardımıyla bizim gibi erişemeyiz []
.
Ayrıca; mipadi'nin cevabında söylediği gibi ; Temel olarak nesnenin __getitem__()
yöntemi uyguladığı anlamına gelir . (aboneliğiniz varsa). Böylece üretilen hata:
arr.append["HI"]
TypeError: 'builtin_function_or_method' nesnesi abone edilemez
Ben de aynı sorunu yaşadım. yapıyordum
arr = []
arr.append["HI"]
Yani kullanmak [
hataya neden oluyordu. Olmalıarr.append("HI")
Buradaki önceki yanıtların bir sonucu olarak, çoğu zaman bu, olmadığınızda bir listeniz (veya dikteniz veya başka bir abonelik nesnesi) olduğunu düşündüğünüzün bir işaretidir.
Örneğin, bir liste döndürmesi gereken bir fonksiyonunuz olduğunu varsayalım ;
def gimme_things():
if something_happens():
return ['all', 'the', 'things']
Şimdi bu işlevi çağırdığınızda ve something_happens()
bir nedenden dolayı bir True
değer döndürmediğinizde ne olur? if
Eğer aracılığıyla düşmek böylece başarısız olur ve; gimme_things
açıkça return
hiçbir şey yapmaz - o zaman aslında, dolaylı olarak olacaktır return None
. Sonra bu kod:
things = gimme_things()
print("My first thing is {0}".format(things[0]))
başarısız olur NoneType
"çünkü iyi, nesne İndislenebilir değil" things
ise None
ve siz yapmaya çalışıyoruz bu yüzden None[0]
hata mesajı ne diyor çünkü ... mantıklı değil hangi.
Kodunuzdaki bu hatayı düzeltmenin iki yolu vardır - birincisi, things
kullanmaya başlamadan önce aslında geçerli olup olmadığını kontrol ederek hatayı önlemektir ;
things = gimme_things()
if things:
print("My first thing is {0}".format(things[0]))
else:
print("No things") # or raise an error, or do nothing, or ...
veya TypeError
istisnayı eşit olarak tuzağa düşürmek ;
things = gimme_things()
try:
print("My first thing is {0}".format(things[0]))
except TypeError:
print("No things") # or raise an error, or do nothing, or ...
Bir diğeri, gimme_things
her zaman bir liste döndürdüğünden emin olmak için yeniden tasarlamaktır . Bu durumda, muhtemelen daha basit bir tasarımdır, çünkü benzer bir hatanın olduğu birçok yer varsa, basit ve deyimsel tutulabilir.
def gimme_things():
if something_happens():
return ['all', 'the', 'things']
else: # make sure we always return a list, no matter what!
logging.info("Something didn't happen; return empty list")
return []
Tabii ki, else:
şubeye koyduğunuz şey kullanım durumunuza bağlıdır. Belki bir something_happens()
şeylerin yanlış gittiğini daha açık ve net hale getirmek için başarısız olduğunda bir istisna ortaya koymalısınız? Kendi kodunuza istisnalar eklemek, bir şey başarısız olduğunda neyin olduğunu tam olarak bilmenin önemli bir yoludur!
(Ayrıca, bu ikinci düzeltmenin hatayı nasıl tamamen düzeltmediğine de dikkat edin - abone olmaya çalışmanızı engeller None
ama things[0]
bir hala IndexError
zaman things
boş bir listedir Eğer bir varsa. try
Yapabileceğiniz except (TypeError, IndexError)
de tuzağa bunu için.)
hasattr(SomeClassWithoutGetItem, '__getitem__')
bir şeyin abonelenebilir olup olmadığını belirlemek için?