【发布时间】:2017-04-20 05:23:40
【问题描述】:
我首先要强调的是,我已经广泛地搜索了网络和 Python 文档 + StackOverflow,并且没有设法找到这个问题的答案。我还要感谢任何花时间阅读本文的人。
正如标题所示,我正在用 Python 编写一个装饰器,我希望它为包装函数添加关键字参数(请注意:我知道如何为装饰器本身添加参数,这不是我要问的)。
这是我为 Python 3(特别是 Python 3.5)编写的一段代码的工作示例。它使用装饰器参数,将关键字参数添加到包装函数,并定义新函数并将其添加到包装函数。
from functools import wraps
def my_decorator(decorator_arg1=None, decorator_arg2=False):
# Inside the wrapper maker
def _decorator(func):
# Do Something 1
@wraps(func)
def func_wrapper(
*args,
new_arg1=False,
new_arg2=None,
**kwds):
# Inside the wrapping function
# Calling the wrapped function
if new_arg1:
return func(*args, **kwds)
else:
# do something with new_arg2
return func(*args, **kwds)
def added_function():
print("Do Something 2")
func_wrapper.added_function = added_function
return func_wrapper
return _decorator
现在这个装饰器可以通过以下方式使用:
@my_decorator(decorator_arg1=4, decorator_arg2=True)
def foo(a, b):
print("a={}, b={}".format(a,b))
def bar():
foo(a=1, b=2, new_arg1=True, new_arg2=7)
foo.added_function()
现在,虽然这适用于 Python 3.5(我假设适用于任何 3.x),但我还没有设法使其适用于 Python 2.7。我在第一行得到一个SyntaxError: invalid syntax,它试图为func_wrapper 定义一个新的关键字参数,这意味着在导入包含此代码的模块时声明new_arg1=False, 的行。
将新关键字移动到func_wrapper 的参数列表的开头解决了SyntaxError,但似乎与包装函数的签名不一致;我现在在调用foo(1, 2) 时收到错误TypeError: foo() takes exactly 2 arguments (0 given)。如果我像foo(a=1, b=2) 那样明确地分配参数,这个错误就会消失,但这显然还不够——不出所料,我的新关键字参数似乎“窃取”了发送到包装函数的前两个位置参数。这是 Python 3 所没有的。
我很想在这方面得到您的帮助。感谢您抽出宝贵时间阅读本文。
谢伊
【问题讨论】:
-
代码不能按原样运行:你需要导入functools,并且added_function中有一个语句(可能是print("add_function"))。
-
@RoryYorke 已编辑!谢谢,人! :)
-
我在同一时间问这个问题真有趣(比你晚了 20 分钟)。很好,在我完成提问之后和按下“发布您的问题”按钮之前,我重新查看了“可能已经有你答案的问题”。
标签: python-2.7 decorator python-decorators functools