Estou vendo algum código Python que usou o @
símbolo, mas não tenho idéia do que ele faz. Também não sei o que procurar ao pesquisar documentos do Python ou o Google não retorna resultados relevantes quando o @
símbolo é incluído.
python
syntax
python-decorators
AJ00200
fonte
fonte
Exemplo
Isso mostra que o
function
/method
/class
Você está definindo depois de um decorador é apenas basicamente repassados como umaargument
aofunction
/method
imediatamente após o@
sinal.Primeira vista
O Flask de microframework apresenta decoradores desde o início no seguinte formato:
Por sua vez, isso se traduz em:
Perceber isso finalmente me permitiu sentir-me em paz com o Flask.
fonte
app.route("/")
: esta função retorna uma função, que você invocar com o seuhello()
como um argumentoapp.route("/", hello)
imediatamente após definirhello
, ou mesmo definirhello
como um lambda nos argumentos paraapp.route
? (O último exemplo é comum com ashttp.Server
rotas Node.js e Express.)Este trecho de código:
É equivalente a este código:
Na definição de um decorador, você pode adicionar algumas coisas modificadas que não seriam retornadas por uma função normalmente.
fonte
No Python 3.5, você pode sobrecarregar
@
como operador. É nomeado como__matmul__
, porque foi projetado para fazer a multiplicação de matrizes, mas pode ser o que você quiser. Veja PEP465 para detalhes.Esta é uma implementação simples da multiplicação de matrizes.
Este código produz:
fonte
@=
operador (no local), que é__imatmul__
.__add__
e estou__sub__
vinculado a + e - respectivamente, mas nunca ouvi falar do@
sinal antes. Existem outros por aí?O que o símbolo "at" (@) faz no Python?
Em resumo, é usado na sintaxe do decorador e na multiplicação de matrizes.
No contexto dos decoradores, esta sintaxe:
é equivalente a isso:
No contexto da multiplicação de matrizes,
a @ b
chamaa.__matmul__(b)
- fazendo esta sintaxe:equivalente a
e
equivalente a
onde
dot
é, por exemplo, a função de multiplicação da matriz numpy ea
eb
são matrizes.Como você pôde descobrir isso sozinho?
Se você deseja ter uma visão bastante completa do que uma parte específica da sintaxe python faz, consulte diretamente o arquivo de gramática. Para o ramo Python 3:
Podemos ver aqui que
@
é usado em três contextos:Sintaxe do decorador:
Uma pesquisa no google por "decorator python docs" fornece como um dos principais resultados, a seção "Compound Statements" da "Python Language Reference". Rolar para baixo até a seção sobre definições de funções , que podemos encontrar pesquisando a palavra "decorador", vemos que ... há muito o que ler. Mas a palavra "decorador" é um link para o glossário , que nos diz:
Então, nós vemos isso
é semanticamente o mesmo que:
Eles não são exatamente iguais porque o Python avalia a expressão foo (que pode ser uma pesquisa pontilhada e uma chamada de função) antes da barra com a
@
sintaxe decorator ( ), mas avalia a expressão foo após a barra no outro caso.(Se essa diferença faz diferença no significado do seu código, você deve reconsiderar o que está fazendo da sua vida, porque isso seria patológico.)
Decoradores empilhados
Se voltarmos à documentação da sintaxe de definição de função, veremos:
Esta é uma demonstração que podemos chamar de uma função que é decoradora primeiro, assim como decoradores de pilha. Funções, em Python, são objetos de primeira classe - o que significa que você pode passar uma função como argumento para outra função e retornar funções. Decoradores fazem as duas coisas.
Se empilharmos decoradores, a função, conforme definida, é passada primeiro para o decorador imediatamente acima dela, depois a próxima e assim por diante.
Isso resume o uso
@
no contexto dos decoradores.O operador,
@
Na seção de análise lexical da referência de idioma, temos uma seção sobre operadores , que inclui
@
, o que o torna também um operador:e na próxima página, o Modelo de Dados, temos a seção Emulando Tipos Numéricos ,
E vemos que isso
__matmul__
corresponde a@
. Se procurarmos na documentação por "matmul", obtemos um link para O que há de novo no Python 3.5 com "matmul" sob o cabeçalho "PEP 465 - Um operador de infix dedicado para multiplicação de matrizes".(Então agora aprendemos que
@=
é a versão local). Explica ainda:Embora esse operador possa estar sobrecarregado para fazer quase qualquer coisa,
numpy
por exemplo, usaríamos essa sintaxe para calcular o produto interno e externo de matrizes e matrizes:Multiplicação de matriz no local:
@=
Ao pesquisar o uso anterior, aprendemos que também há a multiplicação de matrizes no local. Se tentarmos usá-lo, podemos descobrir que ainda não está implementado para numpy:
Quando é implementado, eu esperaria que o resultado fosse assim:
fonte
@ symbol é um açúcar sintático que o python fornece para utilizar
decorator
,parafraseando a pergunta: é exatamente sobre o que o decorador faz no Python?
Simplificando,
decorator
você pode modificar a definição de uma determinada função sem tocar na parte mais interna (é o fechamento).É o caso mais importante quando você importa um pacote maravilhoso de terceiros. Você pode visualizá-lo, pode usá-lo, mas não pode tocar seu interior e seu coração.
Aqui está um exemplo rápido,
suponha que eu defina uma
read_a_book
função no IpythonVocê vê, eu esqueci de adicionar um nome a ele.
Como resolver esse problema? Obviamente, eu poderia redefinir a função como:
No entanto, e se eu não tiver permissão para manipular a função original ou se houver milhares dessa função a ser manipulada.
Resolva o problema pensando diferente e defina uma nova função
Então empregue.
Tada, você vê, eu alterei
read_a_book
sem tocar no fechamento interno. Nada me deixa equipadodecorator
.Sobre o quê
@
@add_a_book
é uma maneira elegante e prática de dizerread_a_book = add_a_book(read_a_book)
, é um açúcar sintático, não há nada mais sofisticado nisso.fonte
Se você está se referindo a algum código em um notebook python que está usando a biblioteca Numpy ,
@ operator
significa Multiplicação de matriz . Por exemplo:fonte
Começando com o Python 3.5, o '@' é usado como um símbolo de infixo dedicado para MATRIX MULTIPLICATION (PEP 0465 - consulte https://www.python.org/dev/peps/pep-0465/ )
fonte
Decoradores foram adicionados ao Python para facilitar a leitura e o entendimento da função e do método (uma função que recebe uma função e retorna uma aprimorada). O caso de uso original deveria ser capaz de definir os métodos como métodos de classe ou métodos estáticos no início de sua definição. Sem a sintaxe do decorador, seria necessária uma definição esparsa e repetitiva:
Se a sintaxe do decorador for usada para a mesma finalidade, o código será mais curto e fácil de entender:
Sintaxe geral e possíveis implementações
O decorador geralmente é um objeto nomeado ( expressões lambda não são permitidas ) que aceita um único argumento quando chamado (será a função decorada) e retorna outro objeto que pode ser chamado. "Callable" é usado aqui em vez de "function" com premeditação. Embora os decoradores sejam frequentemente discutidos no escopo de métodos e funções, eles não se limitam a eles. De fato, qualquer coisa que possa ser chamada (qualquer objeto que implemente o método _call__ é considerado que pode ser chamado), pode ser usado como um decorador e, freqüentemente, os objetos retornados por elas não são funções simples, mas mais instâncias de classes mais complexas implementando seu próprio método __call_.
A sintaxe do decorador é simplesmente apenas um açúcar sintático . Considere o seguinte uso do decorador:
Isso sempre pode ser substituído por uma chamada explícita do decorador e a reatribuição de função:
No entanto, o último é menos legível e também muito difícil de entender se vários decoradores forem usados em uma única função. Os decoradores podem ser usados de várias maneiras diferentes, como mostrado abaixo:
Como uma função
Existem várias maneiras de escrever decoradores personalizados, mas a maneira mais simples é escrever uma função que retorne uma subfunção que encerre a chamada de função original.
Os padrões genéricos são os seguintes:
Como uma classe
Embora os decoradores quase sempre possam ser implementados usando funções, há algumas situações em que usar classes definidas pelo usuário é uma opção melhor. Isso geralmente acontece quando o decorador precisa de parametrização complexa ou depende de um estado específico.
O padrão genérico para um decorador não parametrizado como uma classe é o seguinte:
Parametrizar decoradores
No código real, geralmente é necessário usar decoradores que podem ser parametrizados. Quando a função é usada como decorador, a solução é simples - um segundo nível de embalagem precisa ser usado. Aqui está um exemplo simples do decorador que repete a execução de uma função decorada o número especificado de vezes toda vez que é chamada:
O decorador definido desta maneira pode aceitar parâmetros:
Observe que, mesmo que o decorador parametrizado possua valores padrão para seus argumentos, os parênteses após o nome serão obrigatórios. A maneira correta de usar o decorador anterior com argumentos padrão é a seguinte:
Por fim, vamos ver decoradores com Propriedades.
Propriedades
As propriedades fornecem um tipo de descritor interno que sabe como vincular um atributo a um conjunto de métodos. Uma propriedade recebe quatro argumentos opcionais: fget, fset, fdel e doc. O último pode ser fornecido para definir uma sequência de documentos vinculada ao atributo como se fosse um método. Aqui está um exemplo de uma classe Rectangle que pode ser controlada pelo acesso direto a atributos que armazenam dois pontos de canto ou usando as propriedades width e height:
A melhor sintaxe para criar propriedades é usar property como um decorador. Isso reduzirá o número de assinaturas de método dentro da classe e tornará o código mais legível e de manutenção . Com os decoradores, a classe acima se torna:
fonte
Para dizer o que os outros têm de uma maneira diferente: sim, é um decorador.
No Python, é como:
Isso pode ser usado para todos os tipos de coisas úteis, possíveis porque as funções são objetos e são necessárias apenas instruções.
fonte
@ Símbolo também é usado para variáveis de acesso dentro de um plydata / pandas trama de dados de consulta,
pandas.DataFrame.query
. Exemplo:fonte
Indica que você está usando um decorador. Aqui está o exemplo de Bruce Eckel de 2008.
fonte