在python中将默认参数传递给装饰器

时间:2015-07-30 15:44:13

标签: python arguments decorator python-decorators

我试图找到一种方法将我的函数默认参数传递给装饰器。我不得不说我对装饰师业务还不熟悉,所以也许我只是不理解它,但我还没有找到任何答案。

所以这里是我在python functools.wraps手册页中的修改示例。

from functools import wraps
def my_decorator(f):
    @wraps(f)
    def wrapper(*args, **kwds):
            print 'Calling decorated function'
            print 'args:', args 
            print 'kwargs:', kwds   
            return f(*args, **kwds)
    return wrapper

@my_decorator
def example(i, j=0):
    """Docstring"""
    print 'Called example function'

example(i=1)

我也希望传递j=0。所以输出应该是:

Calling decorated function
args: ()
kwargs: {'i': 1, 'j': 0}
Called example function

2 个答案:

答案 0 :(得分:1)

您可以使用__defaults__特殊属性获取默认参数值。

def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
    print('def args values', f.__defaults__)
    return f(*args, **kwds)
return wrapper

参考:在https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy

中查找__defaults__
  

包含具有默认值的参数的默认参数值的元组,如果没有参数具有默认值,则为None

答案 1 :(得分:0)

默认参数是函数签名的一部分。在装饰器调用中不存在。

因此要在包装器中使用它,您需要像this问题中所示将其取出。

import inspect

def get_default_args(func):
    signature = inspect.signature(func)
    return {
        k: v.default
        for k, v in signature.parameters.items()
        if v.default is not inspect.Parameter.empty
    }

def my_decorator(f):
    @wraps(f)
    def wrapper(*args, **kwds):
            print('Calling decorated function')
            print('args:', args)
            kwargs = get_default_args(f)
            kwargs.update(kwds)
            print('kwargs:', kwargs)
            return f(*args, **kwds)
    return wrapper

@my_decorator
def example(i, j=0):
    """Docstring"""
    print('Called example function')

example(i=1)

输出:

Calling decorated function
args: ()
kwargs: {'i': 1, 'j': 0}
Called example function