python - Decorators influencing sys._getframe(1) -
a.py
import d d.funcme('blah')
d.py
import sys import errors def argcheck(in_=(), out=(type(none),)): def _argcheck(function): # here def __argcheck(*args, **kw): print '+++++++++ checking types before calling func' # here res = function(*args, **kw) return res return __argcheck return _argcheck @argcheck((str)) <----- def funcme(name): try: f = sys._getframe(1) except valueerror, err: raise errors.usererror(err) # stack deep filename, lineno = f.f_globals['__name__'], f.f_lineno print filename, lineno
output without argcheck decorator (comment out @argcheck((str))
):
$ python a.py __main__ 3
output argcheck
decorator:
$ python a.py +++++++++ checking types before calling func defines 9
questions:
what's decorator doing it's changing values
_getframe
?how can preserve information captures original information i.e
__main__
3 , not defines 9?
the problem yourfuncme()
function assuming has been called directly rather indirectly through else — such decorator. fixed changing calling sequence , adding additionaldepth
keyword argument default value passed on _sys._getframe()
. scaffolding in place, decorator can override default value. following print same thing whether or not decorator has been applied:
1 import sys 2 import errors 3 def argcheck(in_=(), out=(type(none),)): 4 def _argcheck(function): 5 # here 6 def __argcheck(*args, **kw): 7 print '+++++++++ checking types before calling func' 8 # here 9 res = function(*args, depth=2, **kw) # override default depth 10 return res 11 return __argcheck 12 return _argcheck 13 14 @argcheck((str)) 15 def funcme(name, depth=1): # added keyword arg default value 16 try: 17 f = sys._getframe(depth) # explicitly pass stack depth wanted 18 except valueerror, err: 19 raise errors.usererror(err) # stack deep 20 21 filename, lineno = f.f_globals['__name__'], f.f_lineno 22 print filename, lineno
Comments
Post a Comment