Как я могу программно изменить аргумент функции в декораторе Python?
Дана функция:
def func(f1, kw='default'):
pass
bare_argspec = inspect.getargspec(func)
@decorator
def func2(f1, kw='default'):
pass
decorated_argspec = inspect.getargspec(func2)
Как я могу создать декоратор такой, что bare_argspec == decorated_argspec
?
(Что касается того, почему каркас, который вызывает декорированную функцию, выполняет проверку argspec, чтобы выбрать, что передать, поэтому декоратор должен сохранить тот же аргумент argspec, чтобы играть хорошо. Когда я задал этот вопрос на #python, я получил длинный речь о том, почему фреймворк отстой, а это не то, что я ищу, я должен решить проблему здесь. Кроме того, я просто заинтересован в ответе тоже)
3 ответа
Модуль декоратора Микеле Симионато имеет декоратор под названием декоратор, который сохраняет функцию argspecs.
import inspect
import decorator
def func(f1, kw='default'):
pass
bare_argspec = inspect.getargspec(func)
print(bare_argspec)
# ArgSpec(args=['f1', 'kw'], varargs=None, keywords=None, defaults=('default',))
@decorator.decorator
def mydecorator(func,*args,**kw):
result=func(*args,**kw)
return result
@mydecorator
def func2(f1, kw='default'):
pass
decorated_argspec = inspect.getargspec(func2)
print(decorated_argspec)
# ArgSpec(args=['f1', 'kw'], varargs=None, keywords=None, defaults=('default',))
assert(bare_argspec==decorated_argspec)
Там есть модуль декоратора:
from decorator import decorator
@decorator
def trace(func, *args, **kw):
print 'calling', func, 'with', args, kw
return func(*args, **kw)
Что делает trace
декоратор с теми же аргументами, что и оформленная функция. Пример:
>>> @trace
... def f(x, y=1, z=2, *args, **kw):
... pass
>>> f(0, 3)
calling f with (0, 3, 2), {}
>>> from inspect import getargspec
>>> print getargspec(f)
ArgSpec(args=['x', 'y', 'z'], varargs='args', keywords='kw', defaults=(1, 2))
Являются functools.update_wrapper()
и / или functools.wraps()
достаточно хорошо?