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

前端 未结 3 1715
醉话见心
醉话见心 2020-12-07 00:52

Given a function:

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

@decorator
def func2(f1, kw=\'default\'):
    pass
decorate         


        
相关标签:
3条回答
  • 2020-12-07 01:19

    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)
    
    0 讨论(0)
  • 2020-12-07 01:26

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

    0 讨论(0)
  • 2020-12-07 01:36

    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))
    
    0 讨论(0)
提交回复
热议问题