Wat betekent het als een Python-object “subscriptable” is of niet?

Welke soorten objecten vallen in het domein van “subscriptable”?


1, Autoriteit 100%

Het betekent eigenlijk dat het object de __getitem__()-methode implementeert. Met andere woorden, het beschrijft objecten die “containers” zijn, wat betekent dat ze andere objecten bevatten. Dit omvat snaren, lijsten, tuples en woordenboeken.


2, Autoriteit 21%

Van de bovenkant van mijn hoofd zijn de volgende de enige ingebouwde ins die subcriptable zijn:

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

Maar het antwoord van Mipadi is correct – elke klasse die implementeert __getitem__is subscriptable


3, Autoriteit 4%

Een schriftbaar object is een object dat de bewerkingen hierop registreert en het kan ze opslaan als een “script” dat kan worden herhaald.

Zie bijvoorbeeld: Toepassing Scripting Framework

Nu, als Alistair niet wist wat hij vroeg en werkelijk “subscriptieable” objecten (zoals bewerkt door anderen), dan (zoals MIPADI ook beantwoord) Dit is de juiste:

Een subscriptable object is elk object dat de __getitem__speciale methode (denktlijsten, woordenboeken) implementeert.


4, Autoriteit 4%

De betekenis van subscript in computing is:
“Een symbool (notionaal geschreven als subcript, maar in de praktijk meestal niet) gebruikt in een programma, alleen of met anderen, om een ​​van de elementen van een array te specificeren.”

Nu, in het eenvoudige voorbeeld van @ user2194711 We kunnen zien dat het app bij het toevoegen van is niet deel van de lijst vanwege twee redenen: –

1) We noemen niet echt de methode append; Omdat het ()nodig heeft om het te noemen.

2) De fout geeft aan dat de functie of methode niet subscriptable is; betekent dat ze niet indexeerbaar zijn zoals een lijst of volgorde.

Zie dit nu: –

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

Dat betekent dat er geen subscripts of zeggen elementen in functionzoals ze in reeksen voorkomen; En we hebben geen toegang tot ze zoals wij, met behulp van [].

ook; zoals Mipadi zei in zijn antwoord; Het betekent eigenlijk dat het object de __getitem__()-methode implementeert. (Als het subscriptable is).
Dus de geproduceerde fout:

arr.append["HI"]

TypeError: ‘BurnedIn_function_or_method’ object is niet subscriptable


5

Als een uitvloeisel van de eerdere antwoorden hier, is dit heel vaak een teken dat u denkt een lijst (of dictaat of ander subscriptbaar object) te hebben, terwijl dat niet het geval is.

Stel bijvoorbeeld dat je een functie hebt die een lijst moetteruggeven;

def gimme_things():
    if something_happens():
        return ['all', 'the', 'things']

Als je die functie aanroept en something_happens()om de een of andere reden geen True-waarde retourneert, wat gebeurt er dan? De ifmislukt, en dus val je er doorheen; gimme_thingsreturnexpliciet iets — dus in feite zal het impliciet return None. Dan deze code:

things = gimme_things()
print("My first thing is {0}".format(things[0]))

zal mislukken met “NoneTypeobject is niet onderschrijfbaar” omdat, nou ja, thingsis Noneen dus probeert u None[0]wat niet logisch is omdat … wat de foutmelding zegt.

Er zijn twee manieren om deze bug in je code op te lossen — de eerste is om de fout te vermijden door te controleren of thingsinderdaad geldig zijn voordat je probeert het te gebruiken;

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

of op equivalente wijze de uitzondering TypeErroropvangen;

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

Een andere is om gimme_thingsopnieuw te ontwerpen, zodat je ervoor zorgt dat het altijd een lijst retourneert. In dit geval is dat waarschijnlijk het eenvoudigere ontwerp, omdat het betekent dat als er veel plaatsen zijn waar je een vergelijkbare bug hebt, ze eenvoudig en idiomatisch kunnen worden gehouden.

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

Natuurlijk, wat je in de else:branch plaatst, hangt af van je use case. Misschien moet je een uitzondering maken wanneer something_happens()faalt, om het duidelijker en explicieter te maken waar er iets mis is gegaan? Het toevoegen van uitzonderingen aan je eigen code is een belangrijke manier om jezelf precies te laten weten wat er aan de hand is als iets niet lukt!

(Let ook op hoe deze laatste oplossing de bug nog steeds niet volledig verhelpt — het voorkomt dat je probeert om Nonete subscripten, maar things[0]is nog steeds een IndexErrorwanneer thingseen lege lijst is. Als je een tryhebt, kun je except (TypeError, IndexError)om het ook te vangen.)

Other episodes