То, как я понимаю декораторы функций в python (и я могу ошибаться), заключается в том, что они должны добавлять побочные эффекты и изменять возвращаемое значение функции. Теперь декораторы добавляются над определением декорируемой функции или по заданию. Вот небольшой пример:
def print_args_decor(function):
def wrapper(*args, **kwargs):
print 'Arguments:', args, kwargs # Added side-effect
return function(*args, **kwargs)*5 # Modified return value
return wrapper
@print_args_decor
def do_stuff(strg, n=10):
"""Repeats strg a few times."""
return strg * n
new_decorated_func = print_args_decor(do_stuff) # Decoration by assignment
print do_stuff('a', 2) # Output: aaaaaaaaaa
Теперь, как прикрепить декоратор к функции, определенной в другом месте, в идеале сохранив исходное имя функции и строку документации (как это делает functools.wraps
)? Например, я импортирую функцию sqrt()
из математического модуля Python и хочу ее украсить, как мне это сделать?
from functools import wraps
from math import sqrt
def print_args_decor(function):
@wraps(function)
def wrapper(*args, **kwargs):
print 'Arguments:', args, kwargs # Added side-effect
return function(*args, **kwargs)*5 # Modified return value
return wrapper
# Decorate the sqrt() function from math module somehow
@print_args_decor #???
sqrt #???
print sqrt(9)
# Output:
# Arguments: ([9],) {}
# 15 # <--- sqrt(9)*5
Как насчет декорирования методов внутри классов постфактум? Как насчет украшения самих классов?