Anotaciones de funciones: PEP-3107
Me encontré con un fragmento de código que demuestra las anotaciones de funciones de Python3. El concepto es simple, pero no puedo pensar por qué se implementaron en Python3 o cualquier buen uso para ellos. ¿Quizás SO puede iluminarme?
Cómo funciona:
def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
... function body ...
Todo lo que sigue a los dos puntos después de un argumento es una 'anotación', y la información que sigue ->
es una anotación para el valor de retorno de la función.
foo.func_annotations devolvería un diccionario:
{'a': 'x',
'b': 11,
'c': list,
'return': 9}
¿Cuál es el significado de tener esto disponible?
python
function
annotations
python-3.x
agscala
fuente
fuente
foo.func_annotations
estarfoo.__annotations__
en python3?def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
significaRespuestas:
Creo que esto es realmente genial.
Viniendo de una formación académica, puedo decirle que las anotaciones han demostrado ser invaluables para permitir analizadores estáticos inteligentes para lenguajes como Java. Por ejemplo, podría definir la semántica como restricciones de estado, subprocesos a los que se les permite acceder, limitaciones de arquitectura, etc., y hay bastantes herramientas que pueden leerlas y procesarlas para proporcionar garantías más allá de lo que obtiene de los compiladores. Incluso podría escribir cosas que verifiquen las condiciones previas / posteriores.
Siento que algo como esto es especialmente necesario en Python debido a su escritura más débil, pero realmente no hubo construcciones que lo hicieran sencillo y parte de la sintaxis oficial.
Hay otros usos para las anotaciones más allá de la seguridad. Puedo ver cómo puedo aplicar mis herramientas basadas en Java a Python. Por ejemplo, tengo una herramienta que le permite asignar advertencias especiales a los métodos, y le da indicaciones cuando las llama para que lea su documentación (por ejemplo, imagine que tiene un método que no debe invocarse con un valor negativo, pero es no intuitivo por el nombre). Con anotaciones, podría escribir técnicamente algo así para Python. Del mismo modo, se puede escribir una herramienta que organice métodos en una clase grande basada en etiquetas si hay una sintaxis oficial.
fuente
Las anotaciones de funciones son lo que haces de ellas.
Se pueden usar para documentación:
Se pueden usar para la verificación previa a la condición:
Consulte también http://www.python.org/dev/peps/pep-0362/ para ver una forma de implementar la verificación de tipos.
fuente
Mass
y, en suVelocity
lugar.def kinetic_energy(mass: 'in kilograms', velocity: 'in meters per second') -> float:
que mostrar el tipo de retorno. Esta es mi respuesta favorita aquí.return
anotación? No parece aparecer enlocals
Esta es una respuesta tardía, pero AFAICT, el mejor uso actual de las anotaciones de funciones es PEP-0484 y MyPy .
Usado así:
fuente
list(fib('a'))
con su función de ejemplo, Python 3.7 acepta felizmente el argumento y se queja de que no hay forma de comparar una cadena y un int.Solo para agregar un ejemplo específico de un buen uso de mi respuesta aquí , junto con los decoradores, se puede hacer un mecanismo simple para métodos múltiples.
y un ejemplo de uso:
Esto se puede hacer agregando los tipos al decorador como lo muestra la publicación original de Guido , pero anotar los parámetros en sí es mejor ya que evita la posibilidad de una coincidencia incorrecta de parámetros y tipos.
Nota : en Python puede acceder a las anotaciones en
function.__annotations__
lugar de eliminarfunction.func_annotations
elfunc_*
estilo en Python 3.fuente
function = self.typemap.get(types)
que no funcionará cuando se incluyan subclases. En ese caso, probablemente tengas que recorrerlotypemap
usandoisinnstance
. Me pregunto si@overload
maneja esto correctamente__annotations__
es undict
que no garantiza el orden de los argumentos, por lo que este fragmento a veces falla. Yo recomendaría cambiar eltypes = tuple(...)
aspec = inspect.getfullargspec(function)
entoncestypes = tuple([spec.annotations[x] for x in spec.args])
.Uri ya ha dado una respuesta adecuada, así que aquí hay una respuesta menos seria: para que pueda acortar sus cadenas de documentos.
fuente
La primera vez que vi anotaciones, pensé "¡genial! ¡Finalmente puedo optar por algún tipo de verificación!" Por supuesto, no me había dado cuenta de que las anotaciones no se aplican realmente.
Así que decidí escribir un decorador de funciones simple para hacerlas cumplir :
Lo agregué a la biblioteca Asegurar .
fuente
Ha pasado mucho tiempo desde que se hizo esto, pero el fragmento de ejemplo dado en la pregunta es (como también se indica allí) de PEP 3107 y al final de este ejemplo de PEP También se dan casos de uso que podrían responder a la pregunta desde el punto de PEP vista;)
Lo siguiente se cita de PEP3107
Casos de uso
En el curso de la discusión de las anotaciones, se han planteado varios casos de uso. Algunos de estos se presentan aquí, agrupados por el tipo de información que transmiten. También se incluyen ejemplos de productos y paquetes existentes que podrían hacer uso de anotaciones.
Consulte la PEP para obtener más información sobre puntos específicos (así como sus referencias)
fuente
Python 3.X (solo) también generaliza la definición de funciones para permitir que los argumentos y los valores de retorno se anoten con valores de objeto para su uso en extensiones .
Sus datos META para explicar, para ser más explícitos sobre los valores de la función.
Las anotaciones se codifican
:value
después del nombre del argumento y antes de un valor predeterminado, y->value
después de la lista de argumentos.Se recopilan en un
__annotations__
atributo de la función, pero Python no los trata como algo especial:EJEMPLO:
El
typeannotations
módulo proporciona un conjunto de herramientas para la verificación de tipos y la inferencia de tipos de código Python. También proporciona un conjunto de tipos útiles para anotar funciones y objetos.Estas herramientas están diseñadas principalmente para ser utilizadas por analizadores estáticos como linters, bibliotecas de finalización de código e IDE. Además, se proporcionan decoradores para realizar comprobaciones de tiempo de ejecución. La comprobación de tipos en tiempo de ejecución no siempre es una buena idea en Python, pero en algunos casos puede ser muy útil.
https://github.com/ceronman/typeannotations
Cómo escribir ayuda a escribir un mejor código
PEP 526 - Sintaxis para anotaciones variables
https://www.python.org/dev/peps/pep-0526/
https://www.attrs.org/en/stable/types.html
fuente
A pesar de todos los usos descritos aquí, el uso obligatorio y, muy probablemente, el uso obligatorio de las anotaciones será para sugerencias de tipo .
Actualmente, esto no se aplica de ninguna manera, pero, a juzgar por PEP 484, las futuras versiones de Python solo permitirán tipos como el valor de las anotaciones.
Citando ¿Qué pasa con los usos existentes de las anotaciones? :
Aunque todavía no he visto ninguna depreciación silenciosa en 3.6, esto podría muy bien pasar a 3.7.
Por lo tanto, a pesar de que puede haber algunos otros buenos casos de uso, es mejor mantenerlos únicamente para sugerencias de tipo si no desea cambiar todo en un futuro donde esta restricción esté vigente.
fuente
Como una respuesta un poco retrasada, varios de mis paquetes (marrow.script, WebCore, etc.) usan anotaciones donde están disponibles para declarar la conversión de texto (es decir, transformar los valores entrantes desde la web, detectar qué argumentos son modificadores booleanos, etc.) como para realizar un marcado adicional de argumentos.
Marrow Script crea una interfaz de línea de comandos completa para funciones y clases arbitrarias y permite definir documentación, conversión y valores predeterminados derivados de la devolución de llamada mediante anotaciones, con un decorador para admitir tiempos de ejecución más antiguos. Todas mis bibliotecas que usan anotaciones admiten los formularios:
El soporte "desnudo" para las cadenas de documentos o las funciones de conversión de texto permite una mezcla más fácil con otras bibliotecas que reconocen las anotaciones. (Es decir, tengo un controlador web que usa la conversión de texto que también está expuesto como un script de línea de comandos).
Editado para agregar: también he comenzado a utilizar el paquete TypeGuard utilizando aserciones de tiempo de desarrollo para la validación. Beneficio: cuando se ejecuta con "optimizaciones" habilitadas (
-O
/PYTHONOPTIMIZE
env var), se omiten las comprobaciones, que pueden ser costosas (por ejemplo, recursivas), con la idea de que ha probado adecuadamente su aplicación en desarrollo, por lo que las comprobaciones deberían ser innecesarias en la producción.fuente
Las anotaciones se pueden usar para modularizar fácilmente el código. Por ejemplo, un módulo para un programa que estoy manteniendo podría definir un método como:
y podríamos pedirle al usuario algo llamado "param1" que es "Necesario para contar" y debería ser un "int". Al final, incluso podemos convertir la cadena dada por el usuario al tipo deseado para obtener la experiencia más libre de problemas.
Vea nuestro objeto de metadatos de función para una clase de código abierto que ayuda con esto y puede recuperar automáticamente los valores necesarios y convertirlos a cualquier tipo deseado (porque la anotación es un método de conversión). Incluso los IDE muestran los autocompletos correctamente y suponen que los tipos están de acuerdo con las anotaciones, un ajuste perfecto.
fuente
Si observa la lista de beneficios de Cython, una de las principales es la capacidad de decirle al compilador qué tipo de objeto es Python.
Puedo imaginar un futuro en el que Cython (o herramientas similares que compilan parte de su código Python) utilizarán la sintaxis de anotación para hacer su magia.
fuente
multiply
función a trabajar solo contra enteros, cuando'na' * 8 + ' batman!'
es completamente válida? ;)