通过func获取* args和** kwargs

时间:2014-04-16 16:17:32

标签: python python-3.x decorator args kwargs

在下面的代码中,如何在不需要包装函数的情况下获得函数f中的* args和** kwargs?

def f(func):
    def wrapper(*args, **kwargs):
        print(args)
        print(kwargs)
        return func(*args,**kwargs)
    return wrapper

@f
def write(text):
    print(text)

# write = a(write)

write('dog')

尝试失败1:

def f(func):
    a=func(*args)
    k=func(**kwargs)

会导致错误:

NameError: global name 'args' is not defined

尝试失败2:

def f(func(*args,**kwargs)):
    a=func(*args)
    k=func(**kwargs)

1 个答案:

答案 0 :(得分:5)

包装函数是必要的,也是Python中装饰器定义如何工作的标准部分。

但是,您可以使用functools.wraps()帮助屏蔽回溯中包装函数的存在:

import functools

def f(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

这将更新包装函数以获得包装函数的名称和docstring。

-

装饰器只不过是传递函数的函数。这段代码......

def dec(func):
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@dec
def myfunc(foo, bar):
    return foo+bar

等同于此代码:

def dec(func):
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

def myfunc(foo, bar):
    return foo+bar

myfunc = dec(myfunc)

注意传递给dec的东西是一个函数,它甚至还没被调用过 - 所以当时没有传递任何参数调用dec。这就是包含函数的原因:它添加了一个层,当调用原始函数时,它将被称为 ,它可以捕获参数。