Risposte:
Fondamentalmente significa che l'oggetto implementa il __getitem__()metodo. In altre parole, descrive oggetti che sono "contenitori", nel senso che contengono altri oggetti. Ciò include stringhe, elenchi, tuple e dizionari.
[... ]indicizzazione è chiamata pedice , poiché equivale alla notazione matematica che utilizza pedici effettivi; ad esempio a[1]Python è ciò che i matematici scriverebbero come a₁ . Quindi "sottoscrivibile" significa "in grado di essere sottoscritto". Il che, in termini di Python, significa che deve essere implementato __getitem__(), poiché a[1]è solo zucchero sintattico per a.__getitem__(1).
hasattrdovrebbe funzionare bene, ma non è il modo Pythonic di fare le cose; La pratica di Python incoraggia Duck Typing . Vale a dire, se hai intenzione di provare a recuperare un oggetto dal tuo oggetto usando un pedice, vai avanti e fallo; se pensi che potrebbe non funzionare perché l'oggetto non è sottoscrivibile, avvolgilo in un tryblocco con un except TypeError.
Al di sopra della mia testa, i seguenti sono gli unici incorporati che sono abbonabili:
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
Ma la risposta di mipadi è corretta: qualsiasi classe implementata __getitem__è iscrivibile
Un oggetto con script è un oggetto che registra le operazioni eseguite e può memorizzarle come "script" che possono essere riprodotti.
Ad esempio, vedere: Application Scripting Framework
Ora, se Alistair non sapeva cosa chiedeva e intendeva davvero oggetti "sottoscrivibili" (come modificato da altri), allora (come anche Mipadi ha risposto) questo è quello corretto:
Un oggetto sottoscrivibile è qualsiasi oggetto che implementa il __getitem__metodo speciale (elenchi di pensiero, dizionari).
Il significato di pedice nell'informatica è: "un simbolo (teoricamente scritto come pedice ma in pratica di solito no) utilizzato in un programma, da solo o con altri, per specificare uno degli elementi di un array".
Ora, nel semplice esempio fornito da @ user2194711 , possiamo vedere che l'elemento aggiunto non è in grado di far parte dell'elenco per due motivi: -
1) Non stiamo davvero chiamando il metodo append; perché deve ()chiamarlo.
2) L'errore indica che la funzione o il metodo non è sottoscrivibile; significa che non sono indicizzabili come un elenco o una sequenza.
Ora vedi questo: -
>>> 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
Ciò significa che non ci sono pedici o elementi dire functioncome si verificano nelle sequenze; e non possiamo accedervi come facciamo noi con l'aiuto di [].
Anche; come diceva mipadi nella sua risposta; Fondamentalmente significa che l'oggetto implementa il __getitem__()metodo. (se è abbonabile). Quindi l'errore ha prodotto:
arr.append["HI"]
TypeError: l'oggetto 'builtin_function_or_method' non è sottoscrivibile
Ho avuto lo stesso problema. stavo facendo
arr = []
arr.append["HI"]
Quindi l'utilizzo [stava causando errori. Dovrebbe esserearr.append("HI")
Come corollario delle risposte precedenti qui, molto spesso questo è un segno che pensi di avere un elenco (o dict, o altro oggetto sottoscrivibile) quando non lo fai.
Ad esempio, supponiamo che tu abbia una funzione che dovrebbe restituire un elenco;
def gimme_things():
if something_happens():
return ['all', 'the', 'things']
Ora quando chiamate quella funzione e something_happens()per qualche motivo non restituisce un Truevalore, cosa succede? I iffallimenti, e così cadi; gimme_thingsnon esplicitamente returnnulla - quindi, in effetti, lo farà implicitamente return None. Quindi questo codice:
things = gimme_things()
print("My first thing is {0}".format(things[0]))
fallirà con "L' NoneTypeoggetto non è sottoscrivibile" perché, beh, lo thingsè Nonee quindi stai cercando di fare ciò None[0]che non ha senso perché ... cosa dice il messaggio di errore.
Esistono due modi per correggere questo errore nel codice: il primo è quello di evitare l'errore controllando che thingssia effettivamente valido prima di tentare di usarlo;
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 ...
o intrappolare equivalentemente l' TypeErroreccezione;
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 ...
Un altro è riprogettare in gimme_thingsmodo da assicurarsi che restituisca sempre un elenco. In questo caso, questo è probabilmente il design più semplice perché significa che se ci sono molti posti in cui hai un bug simile, possono essere mantenuti semplici e idiomatici.
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 []
Naturalmente, ciò che metti nel else:ramo dipende dal tuo caso d'uso. Forse dovresti sollevare un'eccezione quando something_happens()fallisce, per rendere più ovvio ed esplicito dove qualcosa è andato storto? Aggiungere eccezioni al tuo codice è un modo importante per farti sapere esattamente cosa succede quando qualcosa non riesce!
(Nota anche come quest'ultima correzione non risolva ancora completamente il bug: ti impedisce di tentare di iscriverti, Nonema things[0]è ancora un IndexErrorquando thingsè un elenco vuoto. Se ne hai uno trypuoi fare anche except (TypeError, IndexError)per intrappolarlo.)
hasattr(SomeClassWithoutGetItem, '__getitem__')determinare se una cosa è iscrivibile?