tutorial por para lista español dummies difícil comandos aprende aplicaciones python

por - python para dummies español pdf



¿Por qué Python eleva TypeError en lugar de SyntaxError? (2)

Una pregunta puramente por curiosidad. Esta es obviamente una sintaxis inválida:

foo = {} foo[''bar'': ''baz'']

Es obvio lo que sucedió, el desarrollador movió una línea de la definición del diccionario, pero no la cambió de la declaración del diccionario literal a la sintaxis de la asignación (y se ha burlado adecuadamente como resultado).

Pero mi pregunta es, ¿por qué Python eleva TypeError: unhashable type aquí en vez de SyntaxError ? ¿Qué tipo está intentando hachís? Solo haciendo esto:

''bar'': ''baz''

es un SyntaxError, como es esto:

[''bar'': ''baz'']

así que no puedo ver qué tipo se está creando que es inigualable.



Solo quiero agregar algunos detalles a la respuesta de Ignacio (lo cual es genial) y eso me lleva algo de tiempo para entender y para personas como yo que no lo entendieron (puedo ser el único que no lo entendí porque no lo hice). no veo a nadie preguntando, no entendí, pero ¿cómo sabe :)):

la primera vez que me pregunto qué rebanada? indexación del diccionario no acepta rebanar?

pero esta es una pregunta estúpida de mi parte porque olvido que python es dinámico (qué estúpido soy) así que cuando Python compila el código la primera vez que Python no sabe si foo es un diccionario o una lista, simplemente lee cualquier expresión como esta foo [''foo'': ''bar''] como porción, para saber que puedes hacer:

def f(): foo = {} foo[''bar'':''foo'']

y al usar el módulo dis verás que la expresión ''bar'':''foo'' se ha convertido automáticamente en una porción:

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

en la primera vez admito que no pensé en esto y fui directamente al código fuente de Python tratando de entender por qué, porque la __getitems__ de la lista no es como __getitem__ de un diccionario, pero ahora entiendo por qué porque si rebanar y rebanar son inmanejables, debería elevar el unhashable type , así que aquí está el código del diccionario __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; } ....

Espero que esto pueda ayudar a algunas personas como yo a entender la gran respuesta de Ignacio, y lo siento si solo duplico la respuesta de Ignacio :)