在Python跟踪中查找完整路径名
问题内容:
打开Python跟踪时,将提供文件名以及模块和源代码。
是否可以显示文件路径以及文件名?
我在用:
-m trace -t
在下面的示例中,不同目录中有两个不同的 account_bank_statement.py 文件。
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')
这是这个(未回答)问题的重复:跟踪文件路径和行号
一个涉及破解跟踪模块的答案将对我有用。
编辑
一个解决方案,基于以下Alfe的答案。它 具有
侵入性,但确实是我想要的。我离开了模块名,还添加了路径名。我正在使用OpenERP,经常在多个位置定义相同的模块名称。
我尚未发布此答案,因为它确实是Alfe解决方案的改进,因此,如果您愿意,请对其投票进行投票。
(1)将trace.py复制到本地路径(2)进行如下编辑:
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
样本输出
请注意,有两个不同的模块名称,包含在不同的目录中,具有相同的文件名。经过修改的 trace.py *可以处理此问题。
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
允许打补丁,此任务很容易。
复制trace.py
(从/usr/lib/python2.7/
我的情况而言)到本地目录(例如当前目录),然后modname(path)
在该本地副本中修补该功能。该函数将目录从模块路径中删除,因此包信息会丢失。原始包含行
filename, ext = os.path.splitext(base)
可以更改为
filename, ext = os.path.splitext(path)
为了 不 删除目录。
呼叫的输出./trace.py --trace t.py
如下所示:
--- 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。
这样可以解决您的问题吗?
编辑:
根据第二种观点,我提出了一个不同的补丁。
在函数中globaltrace_lt()
,模块名是通过调用派生的modname()
; 修补此呼叫fullmodname()
:
modulename = fullmodname(filename)
我认为这可能是一个不太麻烦的补丁。