我在装饰器中有一些代码,我只想运行一次。稍后将调用许多其他函数(实用程序和其他函数),我想确保其他可能具有此装饰器的函数不会在函数调用嵌套中意外使用。
我还希望能够随时检查当前代码是否已包装在装饰器中。
我已经写了这个,但我只是想看看其他人是否能想到比检查堆栈中的(希望!)唯一函数名更好/更优雅的解决方案。
import inspect
def my_special_wrapper(fn):
def my_special_wrapper(*args, **kwargs):
""" Do some magic, only once! """
# Check we've not done this before
for frame in inspect.stack()[1:]: # get stack, ignoring current!
if frame[3] == 'my_special_wrapper':
raise StandardError('Special wrapper cannot be nested')
# Do magic then call fn
# ...
fn(*args, **kwargs)
return my_special_wrapper
def within_special_wrapper():
""" Helper to check that the function has been specially wrapped """
for frame in inspect.stack():
if frame[3] == 'my_special_wrapper':
return True
return False
@my_special_wrapper
def foo():
print within_special_wrapper()
bar()
print 'Success!'
@my_special_wrapper
def bar():
pass
foo()