python decorator with arguments of decorated function

前端 未结 3 1574
小鲜肉
小鲜肉 2021-01-20 15:19

When I wrap a function with @, how do I make the wrapper function look & feel exactly like the wrapped function? help(function) in particular.<

相关标签:
3条回答
  • 2021-01-20 15:54

    functools.wraps can be used to copy the name and docstring of the function. Copying the original function signature is considerably harder to do from scratch.

    If you use the third-party decorator module, however, then

    import decorator
    
    
    @decorator.decorator
    def wraps(f):
        def call(*args, **kw):
            print('in', f, args, kw) 
            return f(*args, **kw)
        return call
    
    
    def g():pass
    
    @wraps
    def f(a, b = 1, g = g, *args, **kw):
        pass
    
    help(f)
    

    yields

    Help on function f in module __main__:
    
    f(a, b=1, g=<function g>, *args, **kw)
    
    0 讨论(0)
  • 2021-01-20 15:57

    I think the other answers are preferable, but if for some reason you don't want to use an external module, you could always alter your decorator like so:

    def wraps(f):
      def call(*args, **kw):
        print('in', f, args, kw)
        return f(*args, **kw)
    call.__name__ = f.__name__
    call.__doc__ = f.__doc__
    return call
    
    0 讨论(0)
  • 2021-01-20 16:07

    Use functools.wraps:

    from functools import wraps
    
    def wrapper(f):
        @wraps(f)
        def call(*args, **kw):
            print('in', f, args, kw)
            return f(*args, **kw)
        return call
    
    @wrapper
    def f(a, b = 1, g = g, *args, **kw):
        pass
    
    help(f)
    Help on function f in module __main__:
    
    f(a, b=1, g=<function g at 0x7f5ad14a6048>, *args, **kw)
    

    This preserves the __name__ and __doc__ attributes of your wrapped function.

    0 讨论(0)
提交回复
热议问题