I have two decorators, @timeout and @retry code is like this
@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)
I just want to know how can method func() know func_inner has a decorator @timeout? Thanks in advance!
This code:
@timeout(seconds=1)
def func_inner(expire):
time.sleep(expire)
Is essentially equal to:
def func_inner(expire):
time.sleep(expire)
func_inner = timeout(seconds=1)(func_inner)
Method func simply calls func_inner(expire), which is the same as calling timeout(seconds=1)(func_inner)(expire) since the decorator has redefined the function.
Yes, you can see the wrapper inside the function, using inspect or globals, and you can access the wrapper object directly.
Here is a simple example showing some ways to see the wrapper inside the function.
#!/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 )
The above prints out,
in mywrapper
** myfunc inspect : mywrapper
** myfunc globals : mywrapper
wrapper =
<function mywrapper at 0x7f30df0e72a8>
done myfunc
wrapper =
<function mywrapper at 0x7f30df0e72a8>
Note that the name is not the name of your function, but instead it is the wrapper. See the inspect and getframe documentation for more about what information is available.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With