Python 影响系统的装饰器\u getframe(1)
Python 影响系统的装饰器\u getframe(1),python,python-2.x,python-decorators,Python,Python 2.x,Python Decorators,a.py import d d.funcme('blah') import sys import Errors def argcheck(in_=(), out=(type(None),)): def _argcheck(function): # do something here def __argcheck(*args, **kw): print '+++++++++ checking types before callin
a.py
import d
d.funcme('blah')
import sys
import Errors
def argcheck(in_=(), out=(type(None),)):
def _argcheck(function):
# do something here
def __argcheck(*args, **kw):
print '+++++++++ checking types before calling the func'
# do something 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 too deep
filename, lineno = f.f_globals['__name__'], f.f_lineno
print filename, lineno
d.py
import d
d.funcme('blah')
import sys
import Errors
def argcheck(in_=(), out=(type(None),)):
def _argcheck(function):
# do something here
def __argcheck(*args, **kw):
print '+++++++++ checking types before calling the func'
# do something 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 too deep
filename, lineno = f.f_globals['__name__'], f.f_lineno
print filename, lineno
使用argcheck
decorator输出:
$ python a.py
+++++++++ checking types before calling the func
defines 9
问题:
\u getframe
的值的\uuuuu main\uuuu
3而不是定义9Decorator基本上是语法糖。这:
@argcheck((str))
def funcme(name):
与此相同:
funcme = argcheck(str)(funcme)
现在,您可以了解装饰程序更改调用堆栈的原因了
我不知道如何在任意情况下解决这个问题,但是如果您事先知道一些关于装饰器的信息,您也许可以为此对代码进行补偿。您还可以研究一下,也许这会提供一些可能有用的线索。Decorator基本上是语法糖。这:
@argcheck((str))
def funcme(name):
与此相同:
funcme = argcheck(str)(funcme)
现在,您可以了解装饰程序更改调用堆栈的原因了
我不知道如何在任意情况下解决这个问题,但是如果您事先知道一些关于装饰器的信息,您也许可以为此对代码进行补偿。您还可以研究一下,也许这会提供一些可能有用的线索。Decorator基本上是语法糖。这:
@argcheck((str))
def funcme(name):
与此相同:
funcme = argcheck(str)(funcme)
现在,您可以了解装饰程序更改调用堆栈的原因了
我不知道如何在任意情况下解决这个问题,但是如果您事先知道一些关于装饰器的信息,您也许可以为此对代码进行补偿。您还可以研究一下,也许这会提供一些可能有用的线索。Decorator基本上是语法糖。这:
@argcheck((str))
def funcme(name):
与此相同:
funcme = argcheck(str)(funcme)
现在,您可以了解装饰程序更改调用堆栈的原因了
我不知道如何在任意情况下解决这个问题,但是如果您事先知道一些关于装饰器的信息,您也许可以为此对代码进行补偿。您还可以研究一下,也许这会提供一些可能有用的线索。问题是您的
funcme()
函数假定它是通过其他东西直接调用的,而不是通过其他东西间接调用的,例如装饰器。可以通过更改其调用顺序并添加一个附加的带有默认值的depth
关键字参数来修复此问题,该参数将传递给\u sys.\u getframe()
。有了这个脚手架,装饰者就可以覆盖默认值。无论是否应用了装饰器,以下内容都将打印相同的内容:
1 import sys
2 import Errors
3 def argcheck(in_=(), out=(type(None),)):
4 def _argcheck(function):
5 # do something here
6 def __argcheck(*args, **kw):
7 print '+++++++++ checking types before calling the func'
8 # do something 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 with default value
16 try:
17 f = sys._getframe(depth) # explicitly pass stack depth wanted
18 except ValueError, err:
19 raise Errors.UserError(err) # stack too deep
20
21 filename, lineno = f.f_globals['__name__'], f.f_lineno
22 print filename, lineno
问题是,您的
funcme()
函数假定它是通过其他对象(例如装饰器)直接调用的,而不是间接调用的。可以通过更改其调用顺序并添加一个附加的带有默认值的depth
关键字参数来修复此问题,该参数将传递给\u sys.\u getframe()
。有了这个脚手架,装饰者就可以覆盖默认值。无论是否应用了装饰器,以下内容都将打印相同的内容:
1 import sys
2 import Errors
3 def argcheck(in_=(), out=(type(None),)):
4 def _argcheck(function):
5 # do something here
6 def __argcheck(*args, **kw):
7 print '+++++++++ checking types before calling the func'
8 # do something 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 with default value
16 try:
17 f = sys._getframe(depth) # explicitly pass stack depth wanted
18 except ValueError, err:
19 raise Errors.UserError(err) # stack too deep
20
21 filename, lineno = f.f_globals['__name__'], f.f_lineno
22 print filename, lineno
问题是,您的
funcme()
函数假定它是通过其他对象(例如装饰器)直接调用的,而不是间接调用的。可以通过更改其调用顺序并添加一个附加的带有默认值的depth
关键字参数来修复此问题,该参数将传递给\u sys.\u getframe()
。有了这个脚手架,装饰者就可以覆盖默认值。无论是否应用了装饰器,以下内容都将打印相同的内容:
1 import sys
2 import Errors
3 def argcheck(in_=(), out=(type(None),)):
4 def _argcheck(function):
5 # do something here
6 def __argcheck(*args, **kw):
7 print '+++++++++ checking types before calling the func'
8 # do something 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 with default value
16 try:
17 f = sys._getframe(depth) # explicitly pass stack depth wanted
18 except ValueError, err:
19 raise Errors.UserError(err) # stack too deep
20
21 filename, lineno = f.f_globals['__name__'], f.f_lineno
22 print filename, lineno
问题是,您的
funcme()
函数假定它是通过其他对象(例如装饰器)直接调用的,而不是间接调用的。可以通过更改其调用顺序并添加一个附加的带有默认值的depth
关键字参数来修复此问题,该参数将传递给\u sys.\u getframe()
。有了这个脚手架,装饰者就可以覆盖默认值。无论是否应用了装饰器,以下内容都将打印相同的内容:
1 import sys
2 import Errors
3 def argcheck(in_=(), out=(type(None),)):
4 def _argcheck(function):
5 # do something here
6 def __argcheck(*args, **kw):
7 print '+++++++++ checking types before calling the func'
8 # do something 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 with default value
16 try:
17 f = sys._getframe(depth) # explicitly pass stack depth wanted
18 except ValueError, err:
19 raise Errors.UserError(err) # stack too deep
20
21 filename, lineno = f.f_globals['__name__'], f.f_lineno
22 print filename, lineno