我有兴趣创建一个泛型函数并用它来装饰所有其他函数。新函数将包含来自两个函数的参数。实施例
def decorator(func):
Some chunk of code
@decorator
def func(a,b):
print a**2,b**2
return a**2,b**2
#Equivalent func of what I want out of the decorator
def equiv_func(a,b,var):
print var # I want to modify all decorated functions to accept a new
# argument and print it using "print var"
print a**2, b**2
return a**2, b**2
这就是我想出来的......但
def decor(func):
def modify(var,**kwargs):
print var
x,y=func(**kwargs)
return x,y
return modify
@decor
def func(a,b):
print a**2,b**2
return a**2,b**2
>>> func(var="hi",a=4,b=5)
hi
16 25
我使用** kwargs作为计算func参数的方法,但这迫使我使用func(var =“hi”,a = 4,b = 5)而不是func(a = 4,b = 5,var =“hi”)由于** kwargs的定位。
此外,当我需要它时,这个解决方法阻止我在定义我的装饰器时使用** kwargs,因为它已经被用于将参数输入到func中。实施例
def test(**kwargs):
if 'test_ans' in kwargs:
if kwargs['test_ans']=='y':
return True
else:
return False
def decor(func):
def modify(var,**kwargs):
if test(**kwargs): # I need to use **kwargs here, but I also need it to define my
# arguments in func.
print var
x,y=func(**kwargs)
return x,y
return modify
...
# The following is what I expect but due to **kwargs being used for two purposes,
# it doesn't work
>>>func(var='hi',a=4,b=5,test_ans='y')
'hi'
16 25
>>>func(var='hi',a=4,b=5,test_ans='n')
16 25
我希望我的问题很明确。这些例子只是为了说明我面临的限制。它们不是实际代码(我不会编写一个使用** kwargs的测试函数) 感谢任何提前帮助,编码专家!
编辑: 或简单地说,有没有其他方法可以修改func(a,b)到func(a,b,c,d,e,...,** kwargs)而不在装饰器中使用kwargs?
答案 0 :(得分:1)
您可以通过
调用func
func(a=4, b=5, var="hi")
使var
成为关键字参数。
def decor(func):
def modify(*args, **kwargs):
var = kwargs.pop('var', None)
print var
x,y=func(*args, **kwargs)
return x,y
return modify
@decor
def func(a,b):
print a**2,b**2
return a**2,b**2
func(a=4, b=5, var="hi")
func(a=4, b=5)
答案 1 :(得分:1)
试试这个。您可以使用func.func_code.co_varnames
访问函数接受的参数。一旦你知道了,你可以过滤掉其他所有内容。
编辑:这是有限的,因为如果myfunc
接受**kwargs
作为参数,您将无法有效使用此功能。
def print_decorator(func):
def wrapped(*args, **kwargs):
# a tuple of the names of the parameters that func accepts
func_params = func.func_code.co_varnames
# grab all of the kwargs that are not accepted by func
extra = set(kwargs.keys()) - set(func_params)
for kw in extra:
print kwargs.pop(kw)
return func(*args, **kwargs)
return wrapped
@print_decorator
def myfunc(a, b, c=None):
print 'myfunc was passed: a={}, b={}, c={}'.format(a, b, c)
return a, b, c
>>> myfunc(1, b=2, c=3, d=4, e=5)
4
5
myfunc was passed: a=1, b=2, c=3