影响系统的装饰师(1)

2024-06-28 20:42:01 发布

您现在位置:Python中文网/ 问答频道 /正文

a.py

import d

d.funcme('blah')

d.py

^{pr2}$

不带argcheck decorator的输出(注释掉@argcheck((str))):

$ python a.py  
__main__ 3  

argcheck修饰符的输出:

$ python a.py  
+++++++++ checking types before calling the func  
defines 9  

问题:

  1. decorator在做什么来改变_getframe的值?

  2. 如何保存信息,使其捕获原始信息,即__main__3而不是定义9?


Tags: thepyimportmaindecorator修饰符typesblah
2条回答

修饰语基本上是句法糖。这个:

@argcheck((str))
def funcme(name):

与此相同:

^{pr2}$

现在您可以看到装饰器为什么要更改调用堆栈。在

我不知道如何在任意情况下解决这个问题,但是如果您事先知道一些关于decorator的信息,您也许可以补偿您的代码。您还可以查看functools.wraps,也许这会提供一些可能有帮助的线索。在

问题是,^{cd1>}函数假设它是通过其他东西直接间接调用的,例如装饰器。可以通过更改其调用顺序并添加附加的^{cd2>}关键字参数来修复此问题,该参数的默认值将传递给^{{cd3>}。在这个脚手架就位后,装饰器可以覆盖默认值。无论是否应用了装饰器,以下内容都将打印相同的内容:

 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

相关问题 更多 >