我为Tornado RequestHandler写了一个帮手装饰器:
def return_response(method):
@wraps(method)
async def wrapper(self, *args, **kwargs):
response = method(self, *args, **kwargs)
if inspect.isawaitable(response):
response = await response
self.set_status(response.status)
self.write(response.body)
return wrapper
由于某种原因,它失败并出现以下错误:
Traceback (most recent call last):
File ".../.venv/lib/python3.6/site-packages/tornado/web.py", line 1511, in _execute
result = yield result
File ".../.venv/lib/python3.6/site-packages/tornado/gen.py", line 1055, in run
value = future.result()
File ".../.venv/lib/python3.6/site-packages/tornado/concurrent.py", line 238, in result
raise_exc_info(self._exc_info)
File "<string>", line 4, in raise_exc_info
File ".../.venv/lib/python3.6/site-packages/tornado/gen.py", line 307, in wrapper
yielded = next(result)
File "<string>", line 6, in _wrap_awaitable
File ".../src/http_handlers/decorators.py", line 106, in wrapper
response = await response
File ".../src/http_handlers/decorators.py", line 106, in wrapper
response = await response
File ".../src/http_handlers/decorators.py", line 106, in wrapper
response = await response
[Previous line repeated 959 more times]
File ".../src/http_handlers/decorators.py", line 104, in wrapper
response = method(self, *args, **kwargs)
RecursionError: maximum recursion depth exceeded in comparison
仅在应用程序启动一段时间后才会显示此错误。它是Python,Tornado中的错误还是我的代码错了?有人遇到过同样的问题吗?
更新
我设法解决了这个问题。它处于完全不同的地方。我曾经在__new__
方法中在运行时应用这个装饰器。我错误地将它应用于cls
的方法,而不是实际的实例。因此,每当创建一个类的新实例时,方法都会再次被包装。
答案 0 :(得分:1)
也许看看这个What is the maximum recursion depth in Python, and how to increase it?然而答案不是要增加它。
当你继续从内部调用一个函数时,它会不断添加到堆栈中,从而不断填充内存。 Python对此设置了限制,因此您不会遇到堆栈溢出。过了一会儿,你似乎达到了这个限制。
106
的{{1}}行发生的任何事情都会导致在其内部反复调用相同的方法。我不确定在没有看到完整用法的情况下我们能够分辨出究竟发生了什么,但希望这会给你一些想法。
我建议尝试查找递归调用代码的位置,并找出重构程序的方法,以便不会发生。