我有两个装饰器,@timeout和@retry 代码是这样的
@timeout(seconds=1)
def func_inner(expire):
time.sleep(expire)
@retry(
count=2,
message="Failed command after {expire} seconds",
)
def func(expire):
func_inner(expire)
我只想知道func()方法如何知道func_inner有一个装饰器@timeout?预先感谢!
答案 0 :(得分:2)
此代码:
@timeout(seconds=1)
def func_inner(expire):
time.sleep(expire)
基本上等于:
def func_inner(expire):
time.sleep(expire)
func_inner = timeout(seconds=1)(func_inner)
方法func
只需调用func_inner(expire)
,这与调用timeout(seconds=1)(func_inner)(expire)
相同,因为装饰器已经重新定义了该函数。
答案 1 :(得分:1)
是的,您可以使用inspect或globals看到函数内部的包装器,并且可以直接访问包装器对象。
这是一个简单的示例,显示了一些查看函数内部包装的方法。
#!/usr/bin/python
import sys
import inspect
def mydecorator(func):
def mywrapper():
print( 'in mywrapper' )
func()
return mywrapper
@mydecorator
def myfunc():
felf = globals()[inspect.getframeinfo(inspect.currentframe()).function]
print("** myfunc inspect : %s"%felf.__name__)
felf = globals()[sys._getframe().f_code.co_name]
print("** myfunc globals : %s"%felf.__name__)
print( 'wrapper =' )
print( myfunc )
print( 'done myfunc' )
myfunc()
print( 'wrapper =' )
print( myfunc )
上面打印出来,
in mywrapper
** myfunc inspect : mywrapper
** myfunc globals : mywrapper
wrapper =
<function mywrapper at 0x7f30df0e72a8>
done myfunc
wrapper =
<function mywrapper at 0x7f30df0e72a8>
请注意,名称不是函数的名称,而是包装器。有关可用信息的更多信息,请参见inspect和getframe文档。
答案 2 :(得分:0)
只有通过装饰器本身定义的某些特定机制才能检测到它。装饰器仅接受一个函数并在通常情况下返回另一个对象,而Python本身不保留此过程的记录。