在下面的代码中,如何在不需要包装函数的情况下获得函数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)
答案 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
。这就是包含函数的原因:它添加了一个层,当调用原始函数时,它将被称为 ,它可以捕获参数。