PEP 3107 (anotaciones de funciones)

Hola a todos. Decidí comprender completamente las anotaciones de Python y, al mismo tiempo, traducir una serie de PEP que documentan este tema. Comenzaremos con los estándares 3.X y terminaremos con las innovaciones en python 3.8. Debo decir de inmediato que este PEP es uno de los más básicos y su lectura solo es útil para principiantes. Bueno, vamos:


PEP 572 - Anotaciones de funciones

Energía3107
Título:Anotaciones de funciones
AutoresCollin Winter <collinwinter en google.com>, Tony Lownds <tony en lownds.com>
Estado:Final
Un tipo:Estándar
Creado:2-dic-2006
Versión de Python:3.0

Anotación a la norma


Este PEP introduce la sintaxis para agregar anotaciones arbitrarias (metadatos) a las funciones en Python.

Justificación


Las funciones en Python 2.x no tenían una forma integrada de anotar parámetros y devolver valores. Para abordar esta brecha, han aparecido muchas herramientas y bibliotecas. Algunos de ellos usan los decoradores descritos en PEP 318, mientras que otros analizan las funciones de docstring y buscan información allí.

Este PEP está diseñado para proporcionar una forma única y estándar de anotar funciones con el fin de reducir la confusión que ha existido hasta este momento causada por la amplia variación en los mecanismos y la sintaxis.

Funciones básicas de anotación


Antes de comenzar a discutir las anotaciones de características de Python 3.0, primero hablemos de sus características en términos generales:

  1. Las anotaciones para parámetros y valores de retorno de funciones son completamente opcionales.
  2. Las anotaciones no son más que una forma de asociar expresiones arbitrarias con diferentes partes de una función en tiempo de compilación.

    Python en sí no presta atención a las anotaciones. Lo único es que le permite acceder a ellos, que se describe en la sección "Acceso a las anotaciones de funciones" a continuación.

    Las anotaciones solo tienen sentido cuando son interpretadas por bibliotecas de terceros. Pueden hacer lo que quieran con anotaciones de funciones. Por ejemplo, una biblioteca puede usar anotaciones de cadena para proporcionar datos de referencia mejorados, por ejemplo:

    def compile(source: "something compilable",
                filename: "where the compilable thing comes from",
                mode: "is this a single statement or a suite?"):
        ...

    Otra biblioteca puede usar la función de Python y las anotaciones de método para verificar la coincidencia de tipos. Esta biblioteca puede usar anotaciones para mostrar qué tipos de datos de entrada espera y qué tipo de datos devolverá. Quizás será algo como esto:

    def haul(item: Haulable, *vargs: PackAnimal) -> Distance:
        ...

    Repetimos una vez más: las anotaciones de ninguno de los ejemplos en sí mismas tienen ningún significado. Adquieren un significado real solo en combinación con bibliotecas de terceros.
  3. Como se desprende del párrafo 2, este PEP no intenta introducir ningún mecanismo estándar para procesar anotaciones, incluso para los tipos incorporados. Todo este trabajo se asigna a bibliotecas de terceros.

Sintaxis


Parámetros


Las anotaciones de parámetros son expresiones opcionales que siguen al nombre del parámetro en sí:

def foo (a: , b:  = 5):
    ...

En pseudogrammatics, los parámetros ahora se ven así: parámetro [: expresión] [= expresión] . Es decir, las anotaciones, como los valores predeterminados, son opcionales y siempre preceden a las últimas. Al igual que se usa un signo igual para indicar un valor predeterminado, se usan dos puntos para las anotaciones. Todas las expresiones de anotación, como los valores predeterminados, se evalúan cuando se ejecuta una definición de función. Obtener argumentos "extra" (es decir, * args y ** kwargs) tiene la misma sintaxis:

def foo(*args: expression, **kwargs: expression):
    ...

Las anotaciones para parámetros anidados siempre siguen el nombre del parámetro, no el último paréntesis. No se requiere la anotación de cada "nombre" en el parámetro anidado:

def foo((x1, y1: expression),
        (x2: expression, y2: expression)=(None, None)):
    ...

Valores de retorno


Hasta ahora, no hemos proporcionado un ejemplo de cómo anotar el tipo de retorno en las funciones. Esto se hace así:

def sum() -> expression:
    ...

Es decir, el literal -> y algún tipo de expresión ahora pueden seguir la lista de parámetros. Al igual que las anotaciones de parámetros, esta expresión se evaluará cuando se ejecute la definición de la función.

La gramática completa de las declaraciones de funciones es ahora la siguiente:

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
parameters: '(' [typedargslist] ')'
typedargslist: ((tfpdef ['=' test] ',')*
                ('*' [tname] (',' tname ['=' test])* [',' '**' tname]
                 | '**' tname)
                | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
tname: NAME [':' test]
tfpdef: tname | '(' tfplist ')'
tfplist: tfpdef (',' tfpdef)* [',']

Lambdas


Las funciones de Lambda no admiten anotaciones. Por supuesto, la sintaxis podría corregirse agregando la capacidad de "ajustar" los argumentos entre paréntesis, sin embargo, se decidió no realizar dicho cambio, porque:

  1. Esto violaría la compatibilidad con versiones anteriores.
  2. Las lambdas son neutrales y anónimas por definición.
  3. Las lambdas siempre se pueden reescribir como funciones


Obtenga acceso a anotaciones de funciones


Después de la compilación, las anotaciones de funciones están disponibles a través del atributo __annotations__. Este atributo es un diccionario mutable que compara los nombres de las variables y los valores de las anotaciones que se les indican.

El diccionario de __anotaciones__ tiene una clave especial de "retorno". Esta clave está presente solo si también se ha definido una anotación para el valor de retorno de la función. Por ejemplo, la siguiente anotación:

def foo (a: 'x', b: 5 + 6, c: list) -> max (2, 9):
    ...

Se devolverá a través del atributo __annotations__ como:

{'a': 'x',
 'b': 11,
 'c': list,
 'return': 9}

Se eligió el nombre clave "return" porque no puede entrar en conflicto con el nombre del parámetro (cualquier intento de usar return como el nombre del parámetro dará como resultado una excepción SyntaxError).

El atributo __annotations__ estará vacío si la función no tiene anotaciones o si la función se creó a través de una expresión lambda.

Casos de uso


Durante la discusión de las anotaciones, examinamos varias opciones para su uso. Algunos de ellos se presentan aquí y se agrupan de acuerdo con la "clase" de información que se transmite. También se incluyen aquí ejemplos de productos y paquetes existentes que pueden usar anotaciones.

  • Proporcionar información de tipo
    • Verificación de tipo
    • Consejos IDE sobre tipos de argumentos esperados y devueltos
    • Sobrecarga de funciones / funciones genéricas [aprox. la sobrecarga de funciones es popular en otros idiomas y consiste en la existencia de varias funciones con los mismos nombres, pero al mismo tiempo, el número de parámetros aceptados por ellos varía]
    • Puentes entre diferentes lenguajes de programación
    • Adaptación
    • Funciones lógicas predicadas
    • Asignación de una consulta de base de datos
    • Clasificación de parámetros RPC [aprox. Marshaling es el proceso de convertir la información almacenada en la RAM en un formato adecuado para el almacenamiento o la transmisión. RPC - Llamada a procedimiento remoto]
  • Proporcionar otra información
    • Documentación de parámetros y valores de retorno

Biblioteca estándar


Pydoc e inspeccionar módulos


El módulo pydoc mostrará anotaciones en la información de referencia de la función. El módulo de inspección cambiará y admitirá anotaciones.

Enlace a otras PEP


Objetos de firma de función


Los objetos de firma de función deben proporcionar anotaciones de función. El objeto de parámetro y otras cosas pueden cambiar. [aprox. Firma (Firma) de la función - parte de su declaración general, permitiendo que los medios de traducción identifiquen la función entre otros]

Implementación


La implementación de referencia se incluyó en la rama py3k (anteriormente "p3yk") como revisión 53170

Ofertas rechazadas


  • BDFL [. ] , , : « »
  • stdlib , , . .
  • , , .
  • A pesar de una discusión adicional, se decidió no estandarizar el mecanismo para la interacción de la anotación. Tal acuerdo en esta etapa sería prematuro. Queremos permitir que estos acuerdos se desarrollen orgánicamente, en función de una situación real, y no tratar de obligar a todos a utilizar algún tipo de esquema artificial.

All Articles