Je veux juste ajouter quelques détails à Réponse d'Ignacio (ce qui est génial) et cela m'a pris du temps à comprendre et pour les gens comme moi qui n'ont pas compris (je suis peut-être le seul à ne pas avoir compris parce que je n'ai vu personne me demander si je n'avais pas compris, mais qui sait ?) ) :
la première fois, je me demande ce qu'est une tranche ? l'indexation du dictionnaire n'accepte pas les tranches ?
mais c'est une question stupide de ma part parce que j'ai oublié que python est dynamique (comme je suis stupide) donc quand python compile le code pour la première fois, il ne sait pas si le code est dynamique ou non. foo
est un dictionnaire ou une liste, il peut donc lire n'importe quelle expression comme foo['foo':'bar'] comme une tranche, pour savoir que vous pouvez simplement faire :
def f():
foo = {}
foo['bar':'foo']
et en utilisant dis vous verrez que l'expression 'bar':'foo'
a été automatiquement converti en tranche :
dis.dis(f)
2 0 BUILD_MAP 0
3 STORE_FAST 0 (foo)
3 6 LOAD_FAST 0 (foo)
9 LOAD_CONST 1 ('bar')
12 LOAD_CONST 2 ('foo')
15 SLICE+3 <<<<<<<<<<<<<<<<<<<<<< HERE!!!!!!
16 POP_TOP
17 LOAD_CONST 0 (None)
20 RETURN_VALUE
la première fois, j'admets que je n'ai pas pensé à cela et que je suis allé directement au code source de python pour essayer de comprendre pourquoi, parce que l'option __getitems__
de la liste n'est pas comme __getitem__
d'un dictionnaire mais maintenant je comprends pourquoi parce que si c'est une tranche et que la tranche n'est pas hachable, il devrait soulever unhashable type
Voici donc le code du dictionnaire __getitem__
:
static PyObject *
dict_subscript(PyDictObject *mp, register PyObject *key)
{
PyObject *v;
long hash;
PyDictEntry *ep;
assert(mp->ma_table != NULL);
if (!PyString_CheckExact(key) || // if check it's not a string
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key); // check if key (sliceobject) is hashable which is false
if (hash == -1)
return NULL;
}
....
J'espère que cela pourra aider certaines personnes comme moi à comprendre la réponse d'Ignacio, et je suis désolé si je ne fais que répéter la réponse d'Ignacio :)