PEP 3107 (anotações de recursos)

Olá a todos. Decidi entender completamente as anotações do Python e, ao mesmo tempo, traduzir uma série de PEPs que documentam este tópico. Começaremos com os padrões 3.X e terminaremos com as inovações no python 3.8. Devo dizer imediatamente que este PEP é um dos mais básicos e que sua leitura é útil apenas para iniciantes. Bem, vamos:


PEP 572 - Anotações de recursos

Pep3107
Título:Anotações de recursos
Autores:Collin Winter <inverno no google.com>, Tony Lownds <tony no lownds.com>
Estado:Final
Um tipo:Padrão
Criada:2 de dezembro de 2006
Versão Python:3.0

Anotação ao padrão


Este PEP apresenta uma sintaxe para adicionar anotações arbitrárias (metadados) a funções no Python.

Justificação


As funções no Python 2.x não tinham uma maneira integrada de anotar parâmetros e retornar valores. Para resolver essa lacuna, muitas ferramentas e bibliotecas apareceram. Alguns deles usam os decoradores descritos no PEP 318, enquanto outros analisam funções de documentação e procuram informações lá.

Esse PEP foi projetado para fornecer uma maneira única e padrão de anotar funções, a fim de reduzir a confusão que existia até esse momento causada pela grande variação de mecanismos e sintaxe.

Noções básicas de anotação de recursos


Antes de começarmos a discutir as anotações dos recursos do Python 3.0, primeiro vamos falar sobre seus recursos em termos gerais:

  1. Anotações para parâmetros e valores de retorno de funções são completamente opcionais.
  2. As anotações nada mais são do que uma maneira de associar expressões arbitrárias a diferentes partes de uma função em tempo de compilação.

    O próprio Python não presta atenção às anotações. A única coisa é que ele permite que você os acesse, descrito na seção "Obtendo acesso às anotações de recursos" abaixo.

    As anotações só fazem sentido quando interpretadas por bibliotecas de terceiros. Eles podem fazer o que quiserem com anotações de função. Por exemplo, uma biblioteca pode usar anotações de cadeia para fornecer dados de referência aprimorados, por exemplo:

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

    Outra biblioteca pode usar anotações de função e método Python para verificar a correspondência de tipos. Essa biblioteca pode usar anotações para mostrar quais tipos de dados de entrada ela espera e que tipo de dados ela retornará. Talvez seja algo assim:

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

    Repetimos mais uma vez: as anotações de nenhum dos exemplos em si têm algum significado. Eles adquirem significado real apenas em combinação com bibliotecas de terceiros.
  3. Como segue o parágrafo 2, este PEP não tenta introduzir nenhum mecanismo padrão para processar anotações, mesmo para tipos internos. Todo esse trabalho é atribuído a bibliotecas de terceiros.

Sintaxe


Parâmetros


As anotações de parâmetro são expressões opcionais após o nome do próprio parâmetro:

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

Na pseudogramática, os parâmetros agora se parecem com: parameter [: expression] [= expression] . Ou seja, as anotações, como valores padrão, são opcionais e sempre precedem a última. Assim como um sinal de igual é usado para indicar um valor padrão, dois pontos são usados ​​para anotações. Todas as expressões de anotação, como valores padrão, são avaliadas quando uma definição de função é executada. Obter argumentos "extras" (ou seja, * args e ** kwargs) tem a mesma sintaxe:

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

As anotações para parâmetros aninhados sempre seguem o nome do parâmetro, não o último colchete. A anotação de cada "nome" no parâmetro aninhado não é necessária:

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

Retornar valores


Até o momento, não fornecemos um exemplo de como anotar o tipo de retorno nas funções. Isso é feito assim:

def sum() -> expression:
    ...

Ou seja, o literal -> e algum tipo de expressão agora podem seguir a lista de parâmetros. Como anotações de parâmetro, essa expressão será avaliada quando a definição da função for executada.

A gramática completa das declarações de função é agora a seguinte:

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


As funções do Lambda não suportam anotações. Obviamente, a sintaxe pode ser corrigida adicionando a capacidade de "agrupar" os argumentos entre colchetes, mas foi decidido não fazer essa alteração, porque:

  1. Isso violaria a compatibilidade com versões anteriores.
  2. Lambdas são neutras e anônimas por definição
  3. Lambdas sempre podem ser reescritas como funções


Tenha acesso às anotações de recursos


Após a compilação, as anotações de função ficam disponíveis através do atributo __annotations__. Este atributo é um dicionário mutável que compara os nomes das variáveis ​​e os valores das anotações indicadas para elas.

O dicionário __annotations__ possui uma chave especial "return". Essa chave está presente apenas se uma anotação também tiver sido definida para o valor de retorno da função. Por exemplo, a seguinte anotação:

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

Será retornado pelo atributo __annotations__ como:

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

O nome da chave “return” foi escolhido porque não pode entrar em conflito com o nome do parâmetro (qualquer tentativa de usar return como o nome do parâmetro resultará em uma exceção SyntaxError).

O atributo __annotations__ ficará vazio se a função não tiver anotações ou se a função foi criada por meio de uma expressão lambda.

Casos de uso


Durante a discussão das anotações, examinamos várias opções para seu uso. Alguns deles são apresentados aqui e agrupados de acordo com a "classe" de informações transmitidas. Também estão incluídos aqui exemplos de produtos e pacotes existentes que podem usar anotações.

  • Fornecendo informações de tipo
    • Verificação de tipo
    • Dicas do IDE sobre tipos de argumento esperado e retornado
    • Sobrecarga de função / funções genéricas [aprox. sobrecarga de função é popular em outros idiomas e consiste na existência de várias funções com o mesmo nome, mas, ao mesmo tempo, o número de parâmetros aceitos por elas varia]
    • Pontes entre diferentes linguagens de programação
    • Adaptação
    • Predicado funções lógicas
    • Mapeando uma Consulta ao Banco de Dados
    • Empacotamento de parâmetros RPC [aprox. Marshaling é o processo de conversão de informações armazenadas na RAM em um formato adequado para armazenamento ou transmissão. RPC - Chamada de Procedimento Remoto]
  • Fornecendo outras informações
    • Documentar parâmetros e valores de retorno

Biblioteca padrão


Pydoc e módulos de inspeção


O módulo pydoc exibirá anotações nas informações de referência da função. O módulo de inspeção será alterado e suportará anotações.

Link para outros PEPs


Função Objetos de Assinatura


Os objetos de assinatura de função devem fornecer anotações de função. Objeto de parâmetro e outras coisas podem mudar. [Aproximadamente. Assinatura (Assinatura) da função - parte de sua declaração geral, permitindo que os meios de tradução identifiquem a função entre outros]

Implementação


A implementação de referência foi incluída na ramificação py3k (anteriormente “p3yk”) como revisão 53170

Ofertas rejeitadas


  • BDFL [. ] , , : « »
  • stdlib , , . .
  • , , .
  • Apesar de uma discussão mais aprofundada, foi decidido não padronizar o mecanismo de interação da anotação. Um acordo nesse estágio seria prematuro. Queremos permitir que esses acordos se desenvolvam organicamente, com base em uma situação real, e não tentar forçar todos a usar algum tipo de esquema artificial.

All Articles