examples - plot() python
Tipo de variable anotaciĆ³n NameError inconsistency (4)
El comportamiento de la variable local (es decir, dentro de la función) se documenta al menos en la sección Efectos en tiempo de ejecución de anotaciones de tipo :
Anotar una variable local hará que el intérprete lo trate como un local, incluso si nunca fue asignado. Las anotaciones para variables locales no serán evaluadas:
def f():
x: NonexistentName # No error.
Y continúa explicando la diferencia para las variables globales:
Sin embargo, si se encuentra en un módulo o nivel de clase, entonces se evaluará el tipo:
x: NonexistentName # Error!
class X:
var: NonexistentName # Error!
El comportamiento me parece sorprendente, por lo que solo puedo ofrecer mi conjetura en cuanto al razonamiento: si ponemos el código en un módulo, Python quiere almacenar las anotaciones.
# typething.py
def test():
a: something = 0
test()
something = ...
a: something = 0
Luego importalo:
>>> import typething
>>> typething.__annotations__
{''a'': Ellipsis}
>>> typething.test.__annotations__
{}
Por qué es necesario almacenarlo en el objeto de módulo, pero no en el objeto de función, todavía no tengo una buena respuesta. Tal vez sea por razones de rendimiento, ya que las anotaciones se realizan mediante análisis de código estático y esos nombres pueden cambiar dinámicamente:
... el valor de tener anotaciones disponibles localmente no compensa el costo de tener que crear y rellenar el diccionario de anotaciones en cada llamada de función. Por lo tanto, las anotaciones a nivel de función no se evalúan y no se almacenan.
En Python 3.6, las nuevas anotaciones variables se introdujeron en el lenguaje.
Pero, cuando un tipo no existe, pueden ocurrir dos cosas diferentes:
>>> def test():
... a: something = 0
...
>>> test()
>>>
>>> a: something = 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name ''something'' is not defined
¿Por qué es diferente el comportamiento de manejo de tipos no existente? ¿No podría causar que uno pase por alto los tipos indefinidos en las funciones?
Notas
Probado con Python 3.6 RC1 y RC2: el mismo comportamiento.
PyCharm resalta something
como "referencia no resuelta" tanto dentro como fuera de la función.
La respuesta más directa para esto (para complementar la respuesta de @ wim) proviene del rastreador de problemas en Github donde se discutió la propuesta:
[..] Finalmente, los lugareños. Aquí creo que no deberíamos almacenar los tipos; el valor de tener las anotaciones disponibles localmente no es suficiente para compensar el costo de crear y llenar el diccionario en cada llamada de función .
De hecho, ni siquiera creo que la expresión de tipo deba evaluarse durante la ejecución de la función . Así por ejemplo:
def side_effect(): print("Hello world") def foo(): a: side_effect() a = 12 return a foo()
No debe imprimir nada. (Un verificador de tipos también se quejaría de que
side_effect()
no es un tipo válido).
Desde el propio BDFL :-) ni un dictado ni una evaluación que se esté realizando.
Actualmente, los objetos de función solo almacenan las anotaciones tal como se proporcionan en su definición:
def foo(a: int):
b: int = 0
get_type_hints(foo) # from typing
{''a'': <class ''int''>}
Crear otro diccionario para las anotaciones de variables locales aparentemente se consideró demasiado costoso.
Puede ir a https://www.python.org/ftp/python/3.6.0/ y descargar la versión RC2 para probar las anotaciones, pero la versión publicada como dice wim aún no se ha publicado. Sin embargo, descargué e intenté su código usando el intérprete de Python3.6 y no se presentaron errores.
Puedes intentar escribir así:
>>>a: ''something'' = 0