【发布时间】:2019-04-20 17:10:02
【问题描述】:
我无法弄清楚这一点,并且不断收到 TypeError。我需要一个装饰器来应用另一个仅在条件成立时才接受参数的装饰器。 TypeError 与传递给 outer() 方法的参数有关。
def decorator(foo, bar):
def wrapped(func):
@wraps(func)
def outer():
...stuff with foo and bar...
return func()
return outer
return wrapped
def conditional(func):
@wraps(func)
def inner():
if some_condition:
raise Error
return decorator(1, 2)(func)
return inner
@app.route('/login', methods=['POST'])
@conditional
def login():
...
这会生成TypeError: outer() takes 0 positional arguments but 2 were given,但有一些基本的打印语句(主要是outer(*args), print(args))我发现它如下:
第一个位置:
{'wsgi.version': (1, 0), 'wsgi.url_scheme': 'http', 'wsgi.input': <_io.BufferedReader name=964>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.run_once': False, 'werkzeug.server.shutdown': <function WSGIRequestHandler.make_environ.<locals>.shutdown_server at 0x0000014341FCA0D0>, 'SERVER_SOFTWARE': 'Werkzeug/0.14.1', 'REQUEST_METHOD': 'POST', 'SCRIPT_NAME': '', 'PATH_INFO': '/login', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': 54900, 'SERVER_NAME': '127.0.0.1', 'SERVER_PORT': '5000', 'SERVER_PROTOCOL': 'HTTP/1.1', 'HTTP_HOST': '127.0.0.1:5000', 'HTTP_USER_AGENT': 'python-requests/2.20.1', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT': '*/*', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_AUTHORIZATION': 'Basic cGF1bDpmb29iYXI=', 'CONTENT_LENGTH': '0', 'werkzeug.request': <Request 'http://127.0.0.1:5000/login' [POST]>}
第二个位置:
<function run_wsgi_app.<locals>.start_response at 0x0000014341FCA378>
我的语法糖在某个地方出错了,不知道在哪里。
通过使用*args 解决了TypeError,但出现了一个新的:
TypeError: 'function' object is not iterable
【问题讨论】:
-
return wrapper与conditional()中的def inner()有什么关系?应该是return inner? -
@MartijnPieters 是的,错别字已修复。
-
条件应该应用一次、导入时还是每次调用URL视图函数?
-
@MartijnPieters 每次调用 URL 视图时。
-
如果条件是
True,条件的目标是根本不应用decorator(1, 2)吗?