我喜欢能够使用settrace
修改get发送到函数的参数,比如:
import sys
def trace_func(frame,event,arg):
value = frame.f_locals["a"]
if value % 2 == 0:
value += 1
frame.f_locals["a"] = value
def f(a):
print a
if __name__ == "__main__":
sys.settrace(trace_func)
for i in range(0,5):
f(i)
这将打印:
1
1
3
3
5
你还可以用settrace
做些什么?
我强烈建议不要滥用settrace。我想你已经明白了,但其他人可能不会。有几个原因:
Settrace是一个非常钝的工具。OP的例子很简单,但实际上没有办法将其扩展到实际系统中使用。
很神秘。任何一个来看你的代码的人都会被它为什么要做它正在做的事情完全难住。
很慢。为执行的每一行Python调用一个Python函数会使程序慢很多倍。
这通常是不必要的。这里的原始示例可以通过其他几种方式(修改函数、将函数包装在装饰器中、通过另一个函数调用它等等)完成,任何一种方式都比settrace好。
很难纠正。在最初的例子中,如果您没有直接调用f,而是调用调用g来调用f,那么您的跟踪函数就不会完成它的工作,因为您没有从跟踪函数返回任何函数,所以它只被调用一次,然后就被遗忘了。
它会阻止其他工具工作。这个程序将无法调试(因为调试器使用settrace)、无法跟踪、无法测量其代码覆盖率等。部分原因是Python实现者缺乏远见:他们给了我们settrace,但没有gettrace,所以很难有两个跟踪函数一起工作。
跟踪功能可以很酷的破解。能滥用它很有趣,但请不要把它用于真正的东西。如果我听起来像是在恐吓,我很抱歉,但这是用真代码做的,而且很痛苦。例如,DecoratorTools使用一个跟踪函数来执行使此语法在Python 2.3中工作的神奇功能:
一个简单的黑客,但不幸的是,这意味着任何使用DecoratorTools的代码都不能与coverage.py(或者我猜是调试器)一起工作。如果你问我,这不是一个好的折衷方案。我更改了coverage.py以提供一种模式,让它可以与DecoratorTools一起工作,但我希望我没有必要这样做。
即使是标准库中的代码有时也会出错。Pyexpat决定与其他扩展模块不同,并像调用Python代码一样调用跟踪函数。可惜他们did a bad job of it。
<;/咆哮>
当然,代码覆盖是通过trace函数实现的。我们以前没有过的一件很酷的事情是分支覆盖率测量,它很好地实现了,即将在alpha版本的coverage.py中发布。
例如,考虑这个函数:
如果用这个电话测试:
然后语句覆盖率将告诉您函数的所有行都已执行。当然,这个函数有一个简单的问题:用0调用它会引发一个UnboundLocalError。
分支度量将告诉您,代码中有一个分支没有完全执行,因为只执行分支的一条腿。
我制作了一个名为^{} 的模块,它使用
sys.settrace()
生成调用图。相关问题 更多 >
编程相关推荐