Decorador é uma função muito importante em Python. Em uma frase, decorador é: passar a função decorada como um parâmetro para a função decorada e realizar as funções redundantes na função decorada.
A seguir, explicamos um por um o que é um decorador:
def f1():
print("Called f1")
print(f1)
<function f1 at 0x7fd2b87b8040>
Definimos uma função f1 e depois imprimimos f1 para exibir o endereço de armazenamento dessa função, ou seja, uma função é um objeto em python, que pode ser passado para outra função como parâmetro.
def f2(f):
f()
f2(f1)
output:
Called f1
Definimos a seguinte função:
def f1(func):
def wrapper():
print("Start")
func()
print("End")
return wrapper
def f():
print("Hello")
Passe f como um parâmetro para f1:
f1(f)
output:
<function __main__.f1.<locals>.wrapper()>
A entrada é uma função. Porque f1 retorna uma função wrapper. A função wrapper não é chamada. A função wrapper é chamada abaixo:
f1(f)()
输出:
Start
Hello
End
Você também pode atribuir a novas variáveis:
f = f1(f)
f()
输入:
Start
Hello
End
Este é o decorador. f é a função decorada , que é passada para a função decorada f1 , e tem as funções internas da função f1. A maneira de escrevê-la com um decorador é:
@f1
def f():
print("Hello")
f()
输出:
Start
Hello
End
Mas não há parâmetros na função decorada aqui, e um erro será gerado se os parâmetros forem passados:
f("hi")
output:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [39], in <cell line: 1>()
----> 1 f("hi")
TypeError: wrapper() takes 0 positional arguments but 1 was given
Se você deseja passar parâmetros na função decorada, pode modificar o decorador da seguinte maneira:
def f1(func):
def wrapper(*args, **kwargs):
print("Start")
func(*args, **kwargs)
print("End")
return wrapper
Deixe o wrapper passar em qualquer forma de parâmetros
@f1
def f(a, b=9):
print(a, b)
f(3)
输出:
Start
3 9
End
As funções decoradas aqui estão todas na forma de print(). Se estiver na forma de return, return pode ser adicionado à função wrapper:
def f1(func):
def wrapper(*args, **kwargs):
print("Start")
val = func(*args, **kwargs)
print("End")
return val
return wrapper
@f1
def add(x, y):
return x + y
print(add(4,5))
输入:
Start
End
9
Para resumir, crie um decorador que dê à função decorada a capacidade de gerar o tempo de execução da função decorada:
import time
def timer(func):
def wrapper():
before = time.time()
func()
print("Function took:", time.time() - before, "seconds")
return wrapper
@timer
def run():
time.sleep(2)
run()
输出:
Function took: 2.005012035369873 seconds