는 더 나은 방법입니다,하지만 당신은 당신이 '보호'하고 싶은 기능에 장식을 추가 할 수 있습니다
from functools import wraps
from threading import local
def recursion_detector(func):
func._thread_locals = local()
@wraps(func)
def wrapper(*args, **kwargs):
params = tuple(args) + tuple(kwargs.items())
if not hasattr(func._thread_locals, 'seen'):
func._thread_locals.seen = set()
if params in func._thread_locals.seen:
raise RuntimeError('Already called this function with the same arguments')
func._thread_locals.seen.add(params)
try:
res = func(*args, **kwargs)
finally:
func._thread_locals.seen.remove(params)
return res
return wrapper
다음 기능을 렌더링 매크로에 그 장식을 적용 할 수 있습니다.
간단한 데모 :
>>> @recursion_detector
... def foo(bar):
... return foo(not bar)
...
>>> foo(True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 10, in wrapper
File "<stdin>", line 3, in foo
File "<stdin>", line 10, in wrapper
File "<stdin>", line 3, in foo
File "<stdin>", line 7, in wrapper
RuntimeError: Already called this function with the same arguments
>>> foo(False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 10, in wrapper
File "<stdin>", line 3, in foo
File "<stdin>", line 10, in wrapper
File "<stdin>", line 3, in foo
File "<stdin>", line 7, in wrapper
RuntimeError: Already called this function with the same arguments
위대한, 고마워! 앞으로의 독자들에게 [this post] (http://stackoverflow.com/a/1894371/684253)는''threading.local''이 어떻게 작동하는지에 대한 좋은 설명과 예제를 제공합니다. –