一些函数参数可以通过装饰器传递吗?
Posted
技术标签:
【中文标题】一些函数参数可以通过装饰器传递吗?【英文标题】:Can some function arguments be passed through decorators? 【发布时间】:2016-06-06 13:19:15 【问题描述】:我有一个功能 -
def add(a, b):
return a+b
现在我希望它使用装饰器将 100 添加到结果中 -
@decorator(100)
def add(a, b):
return (a+b)
class decorator():
def __init__(self, c):
self.c = c
def __call__(self, f):
def _wrapped_f(a, b):
return self.c + f(a, b)
return _wrapped_f
问题是当我想保留额外的参数变量而不是固定为 100。
有点像 -
@decorator(c)
def add(a, b):
return (a+b)
我可以在函数调用期间以某种方式分配这个变量的值吗? (当调用 add 函数时) 我想使用装饰器执行此操作的原因是因为我不想修改我的函数添加。
我无法在函数中提供额外的参数,例如 -
def(a, b, c=0):
return (a+b+c)
因此,需要装饰者。
【问题讨论】:
也就是说,你想让装饰器给函数添加额外的参数? 是的,完全正确。如果不是通过装饰器,还有其他方法可以在不修改实际功能的情况下做到这一点。 好吧,您可以更改_wrapped_f
以采用 (*args, **kwargs)` 参数,然后将所有这些参数相加,但我真的不明白您将如何定义如何在一般情况下处理这些附加参数。当然,仅仅添加更多的东西来添加到结果中并不总是有意义的。
“我无法在函数中提供额外的参数...” 我认为您需要详细说明这一点。为什么不能使用额外的参数?了解这一限制似乎是找到不同解决方案的关键。
【参考方案1】:
当然。装饰器所做的只是用包装的版本替换原始函数;该包装器可以采用任意数量的参数。
我不确定您为什么要使用类 - 作为标准装饰器会更清楚。
def decorator(func):
def wrapped(a, b, c):
return c + func(a, b)
return wrapped
@decorator
def add(a, b):
return (a+b)
【讨论】:
谢谢。全新的装饰器。没想到这么简单。【参考方案2】:不是 100% 确定你想用这个装饰器做什么,所以这可能不是你想要的,但即便如此,其他人可能会觉得它很有用。
您可以向函数添加另一个参数,只需向_wrapped
函数添加更多参数,或者甚至将*args
和**kwargs
传递给该函数。但是你如何处理这些参数呢?当然,仅将这些参数添加到结果中仅对 add
函数有意义。
在一般情况下,您可以使用修饰函数本身来处理附加参数。然后,只需使用原函数的修饰函数reduce
所有参数即可:
from functools import reduce # Python 3
def vararg(f):
""" change two-arg-function into vararg-function"""
def _f(*args):
return reduce(f, args)
return _f
@vararg
def add(a, b):
return a + b
print(add(1, 2)) # -> 3
print(add(1, 2, 3)) # -> 6
print(add(1, 2, 3, 4)) # -> 10
print(add(1, 2, 3, 4, 5)) # -> 15
【讨论】:
以上是关于一些函数参数可以通过装饰器传递吗?的主要内容,如果未能解决你的问题,请参考以下文章