How can I programmatically change the argspec of a function in a python decorator?

心已入冬 提交于 2019-11-26 23:34:33

问题


Given a function:

def func(f1, kw='default'):
    pass
bare_argspec = inspect.getargspec(func)

@decorator
def func2(f1, kw='default'):
    pass
decorated_argspec = inspect.getargspec(func2)

How can I create a decorator such that bare_argspec == decorated_argspec?

(As to why, the framework that calls the decorated function does argspec inspection to choose what to pass in, so the decorator has to retain the same argspec in order to play nice. When I posed this question on #python, I got a long speech about why the framework sucks, which is not what I'm looking for; I have to solve the problem here. Also, I'm just interested in the answer, too)


回答1:


Michele Simionato's decorator module has a decorator called decorator which preserves function 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)



回答2:


There's the decorator module:

from decorator import decorator
@decorator
def trace(func, *args, **kw):
    print 'calling', func, 'with', args, kw
    return func(*args, **kw)

That makes trace a decorator with the same argspecs as the decorated function. Example:

>>> @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))



回答3:


Are functools.update_wrapper() and/or functools.wraps() good enough?



来源:https://stackoverflow.com/questions/3729378/how-can-i-programmatically-change-the-argspec-of-a-function-in-a-python-decorato

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!