Python解释器执行路径的跟踪

4
以下内容可以很好地展示解释器的工作过程:
python -m trace --ignore-dir=$HOME/lib64:$HOME/lib:/usr -t path-to/script.py

但是有太多的行。我希望隐藏在导入文件时发生的行。

例如:我不感兴趣的行像这样:

saved_filter.py(9): class SavedFilter(models.Model):
saved_filter.py(10):     name = models.TextField(max_length=256)
saved_filter.py(11):     user = models.ForeignKey('auth.User', null=True, blank=True)

我在文档中找不到解决方案:https://docs.python.org/2/library/trace.html 更新:如果有其他方法可以获得结果,例如不使用trace的不同python包,那么这也是一个好的解决方案。
更新2:跟踪应该是非交互式的。
更新3:我尝试了Martin v. Löwis提供的解决方案。 在某些情况下它有效,但并不总是有效。
文件foo.py
import bar

def main():
    f=bar.Foo()
    f.my_func()

if __name__=='__main__':
    main()

文件 bar.py

class Foo(object):
    def my_func(self):
        def inner():
            print('#in inner')
            return 'inner'
        print('#in my_func()')
        inner()
        return 1

如果我调用foo.py,期望的结果类似于这样:
foo.py: f=bar.Foo() foo.py: f.my_func() bar.py: print('#在my_func()中') bar.py: inner() bar.py: print('#在inner中') bar.py: return 'inner' bar.py: return 1
trace2.py的结果
> python tmp/trace2-orig.py --trace tmp/foo.py 
 --- modulename: foo, funcname: <module>
 --- modulename: bar, funcname: <module>
 --- modulename: bar, funcname: Foo
bar.py(1): class Foo(object):               <======= Import lines
bar.py(2):     def my_func(self):
 --- modulename: foo, funcname: main
foo.py(4):     f=bar.Foo()
foo.py(5):     f.my_func()
 --- modulename: bar, funcname: my_func
bar.py(3):         def inner():
bar.py(6):         print('#in my_func()')
#in my_func()
bar.py(7):         inner()
 --- modulename: bar, funcname: inner
bar.py(4):             print('#in inner')
#in inner
bar.py(5):             return 'inner'
bar.py(8):         return 1
 --- modulename: trace, funcname: _unsettrace
trace.py(80):         sys.settrace(None)

不幸的是,仍有class Foo(object)这样的东西在导入期间执行。

我猜测代码加载和执行的检测并没有涵盖所有情况。


1
尝试通过在脚本内调用Trace对象方法来收集有关目标函数的信息,并在此之后打印给定的CoverageResults - Andrew Svetlov
3个回答

1
如果您创建一个名为trace2.py的脚本,请保留HTML格式,不要解释。
import trace

OrigTrace = trace.Trace
class Trace2(trace.Trace):
    def localtrace_trace(self, frame, why, arg):
        if why == "line" and frame.f_code.co_name == '<module>':
            return self.localtrace
        return OrigTrace.localtrace_trace(self, frame, why, arg)

trace.Trace=Trace2
trace.main()

如果你运行python -m trace2 -t script.py,你将看不到模块级别的跟踪输出。

非常感谢。我尝试了您的解决方案。它还不能涵盖所有代码加载的情况。请参见更新后的问题。 - guettli

0

你可以使用pdb库,通过这个库,你可以在交互式控制台UI中设置断点和/或注入Python语句到断点行,并执行更多其他操作。 ;)


我更新了问题:跟踪应该是非交互式的。据我所知,pdb 是用于交互式调试的。请告诉我,如果我漏掉了什么。 - guettli

0
如果您只想在导入期间隐藏代码路径,只需通过类似于此的过滤器进行管道传输即可:
import re
import sys

cur = None
skip_re = re.compile(r'^(?P<filename>.+)?\((\d*)\):\s*import')
for line in sys.stdin:
    if cur and not line.startswith(cur):
        continue
    cur = None
    match = skip_re.match(line)
    if match:
        cur = match.group('filename')
    sys.stdout.write(line)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接