Плавное вхождение в понимание - что такое Декораторы:
| Функция без параметров | Функция с одним параметром | Общий случай (много параметров) |
def func_decorator(func):
def wrapper():
print("--before call func-")
func()
print("--after call func--")
return wrapper
def some_func():
print("Вызов функции some_func")
f = func_decorator(some_func)
f()
|
def func_decorator(func):
def wrapper(title):
print("--before call func-")
func(title)
print("--after call func--")
return wrapper
def some_func(title):
print(f"title = {title}")
some_func = func_decorator(some_func)
some_func("Python навсегда!")
|
def func_decorator(func):
def wrapper(*args, **kwargs):
print("--before call func-")
res = func(*args, **kwargs)
print("--after call func--")
return res
return wrapper
def some_func(title, tag):
print(f"title = {title}, tag = {tag}")
return f"<{tag}>{title}</{tag}>"
some_func = func_decorator(some_func)
res = some_func("Python навсегда!", 'h1')
print(res)
|
import time
def test_time(fn):
def wrapper(*args, **kwargs):
st = time.time()
res = fn(*args, **kwargs)
dt = time.time() - st
print(f"Время работы: {dt} сек")
return res
return wrapper
def get_nod(a, b):
while a != b:
if a > b:
a -= b
else:
b -= a
return a
def get_fast_nod(a, b):
if a < b:
a, b = b, a
while b:
a, b = b, a % b
return a
get_nod = test_time(get_nod)
get_fast_nod = test_time(get_fast_nod)
res1 = get_nod(2, 1000000)
res2 = get_fast_nod(2, 1000000)
print(res1, res2)
|
import time
def test_time(fn):
def wrapper(*args, **kwargs):
st = time.time()
res = fn(*args, **kwargs)
dt = time.time() - st
print(f"Время работы: {dt} сек")
return res
return wrapper
@test_time
def get_nod(a, b):
while a != b:
if a > b:
a -= b
else:
b -= a
return a
@test_time
def get_fast_nod(a, b):
if a < b:
a, b = b, a
while b:
a, b = b, a % b
return a
res1 = get_nod(2, 1000000)
res2 = get_fast_nod(2, 1000000)
print(res1, res2)
|
| Обычная запись функции: | ... превращается в запись функции обёрнутой в фикстуру: |
get_nod = test_time(get_nod)
...
|
@test_time
def get_nod(a, b):
...
|
Декоратор (просто):
def deco(f):
def wrap(*args, **kwargs):
print('---- pre ----')
res = f(*args, **kwargs)
print('=== after ===')
return res
return wrap
@deco
def fun(a, b, c):
print('fun print:', a + b + c)
return 'fun return: ' + str(a + b + c)
rf = fun(3, 5, 1)
print(rf)
|
---- pre ---- fun print: 9 === after === fun return: 9 |
Передача параметра через Декоратор:
import math
def df_decorator(dx=0.0001):
def func_decorator(func):
def wrapper(x, *args, **kwargs):
res = (func(x+dx, *args, **kwargs) - func(x, *args, **kwargs)) / dx
return res
wrapper.__doc__ = func.__doc__
return wrapper
return func_decorator
@df_decorator(dx=0.01)
def sin_df(x):
"""Функция для вычисления производной синуса"""
return math.sin(x)
df = sin_df(math.pi/3)
print(df)
print(sin_df.__doc__)
Декоратор с параметром (попроще):
def master_deco(dx=8):
def deco(f):
def wrap(a, b, c, *args, **kwargs):
print('---- pre ----')
res = f(a, b, c + dx, *args, **kwargs)
print('=== after ===')
return res
return wrap
return deco
@master_deco(2)
def fun(a, b, c):
print('fun print:', a + b + c)
return 'fun return: ' + str(a + b + c)
rf = fun(3, 5, 1)
print(rf)
|
---- pre ---- fun print: 11 === after === fun return: 11 |