在 Python 跟踪中查找完整路径名 [英] Finding full pathname in a Python trace

查看:37
本文介绍了在 Python 跟踪中查找完整路径名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

打开 Python 跟踪时,会提供文件名以及模块和源代码.

When turning on Python trace, the filename is provided, along with the module and sourcecode.

是否可以同时显示文件路径和文件名?

Is it possible to show the file path as well as the filename?

我正在使用:

-m trace -t

在下面的示例中,不同目录中有两个不同的 account_bank_statement.py 文件.

In the example below there are two different account_bank_statement.py files in different directories.

17  --- modulename: account_bank_statement, funcname: button_create_invoice
18 account_bank_statement.py(329):         if context is None:
19 account_bank_statement.py(333):         currency =  self.read(cr, uid, ids, ['currency'])[0]['currency']
20  --- modulename: account_bank_statement, funcname: _currency
21 account_bank_statement.py(107):         res = {}
22 account_bank_statement.py(108):         res_currency_obj = self.pool.get('res.currency')

这是这个(未回答的)问题的副本:跟踪文件路径和行号

This is a duplicate of this (unanswered) question: Tracing fIle path and line number

涉及破解跟踪模块的答案对我有用.

An answer that would involve hacking the trace module would work for me.

编辑

一个解决方案,基于下面 Alfe 的回答.它侵入性的,但它确实是我想要的.我已经离开了模块名并添加了路径名.我正在使用 OpenERP,并且经常在多个位置定义相同的模块名称.

A solution, based on Alfe's answer below. It is intrusive, but is does what I an looking for. I have left the modulename and also added the pathname. I am working with OpenERP and there is often the same modulename defined in multiple locations.

我没有发布这个答案,因为它确实是 Alfe 解决方案的改进,所以如果您愿意,请为他的答案投票.

I have not posted this an answer as it is really a refinement of Alfe's solution, so if you like please up vote his answer.

(1) 将 trace.py 复制到本地路径(2) 编辑如下:

(1) Copy trace.py to your local path (2) Edit as below:

171 def modname(path):
172     """Return a plausible module name for the patch."""
173 
174     base = os.path.basename(path)
175     filename, ext = os.path.splitext(base)
176     return filename

593     def globaltrace_lt(self, frame, why, arg):
594         """Handler for call events.
595 
596         If the code block being entered is to be ignored, returns `None',
597         else returns self.localtrace.
598         """
599         if why == 'call':
600             code = frame.f_code
601             filename = frame.f_globals.get('__file__', None)
602             if filename:
603                 # XXX modname() doesn't work right for packages, so
604                 # the ignore support won't work right for packages
605                 #modulename = fullmodname(filename)
606                 modfile, ext = os.path.splitext(filename)
607                 modulename = fullmodname(modfile)
608                 if modulename is not None:
609                     ignore_it = self.ignore.names(modfile, modulename)
610                     if not ignore_it:
611                         if self.trace:
612                             print (" --- modulename: %s, funcname: %s, filename: %s"
613                                    % (modulename, code.co_name, filename))
614                         return self.localtrace
615             else:
616                 return None

样本输出

注意有 2 个不同的模块名称,包含在不同的目录中,具有相同的文件名.这个修改后的 *trace.py** 处理这个.

Note there are 2 different module names, contained in different directories, with the same filenames. This modified *trace.py** handles this.

2  --- modulename: register_accounting, funcname: button_create_invoice, filename: /home/sean/unifield/utp729/unifield-wm/register_accounting/account_bank_statement.pyc
3 account_bank_statement.py(329):         if context is None:
4 account_bank_statement.py(333):         currency =  self.read(cr, uid, ids, ['currency'])[0]['currency']
5  --- modulename: account, funcname: _currency, filename: /home/sean/unifield/utp729/unifield-addons/account/account_bank_statement.pyc
6 account_bank_statement.py(107):         res = {}
7 account_bank_statement.py(108):         res_currency_obj = self.pool.get('res.currency')

推荐答案

如果允许对 trace.py 进行修补,则此任务很容易.

If patching of trace.py is allowed, this task is easy.

复制 trace.py(在我的例子中是从 /usr/lib/python2.7/ )到本地目录(例如当前目录),然后修补函数 modname(path) 在该本地副本中.该函数将目录从模块路径中剥离,因此包信息丢失.原文包含该行

Copy trace.py (from /usr/lib/python2.7/ in my case) to a local directory (e. g. the current one), then patch the function modname(path) in that local copy. That function strips the directories off the module paths, so the package information is lost. The original contains the line

filename, ext = os.path.splitext(base)

可以改成

filename, ext = os.path.splitext(path)

为了剥离目录.

./trace.py --trace t.py 这样的调用的输出看起来像这样:

The output of a call like ./trace.py --trace t.py then looks like this:

 --- modulename: t, funcname: <module>
t.py(3): import mypackage.mymodule
 --- modulename: mypackage/__init__, funcname: <module>
__init__.py(1):   --- modulename: mypackage/mymodule, funcname: <module>
mymodule.py(1): print 42
42
t.py(5): print 5
5
 --- modulename: ./trace, funcname: _unsettrace
trace.py(80):         sys.settrace(None)

我正在跟踪一个名为 t.py 的测试脚本,它导入了一个模块 mymodule.py,它在包 mypackage 中(所以文件名为 ./mypackage/mymodule.py).该模块只打印 42,测试脚本本身打印 5.

I'm tracing a test script called t.py which imports a module mymodule.py which is in a package mypackage (so the filename is ./mypackage/mymodule.py). That module only prints 42, the test script itself prints 5.

这能解决您的问题吗?

根据第二个观点,我提出了一个不同的补丁.

Upon second view, I propose a different patch.

在函数globaltrace_lt()中,模块名是通过调用modname()得到的;修补它以调用 fullmodname():

In function globaltrace_lt() the modulename is derived by calling modname(); patch this to call fullmodname():

            modulename = fullmodname(filename)

我认为这可能是一个侵入性较小的补丁.

I think this might be a less intrusive patch.

这篇关于在 Python 跟踪中查找完整路径名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆