Ale*_*xey 24 python debugging python-module pdb
我知道可以从命令行调试Python脚本
python -m pdb my_script.py
Run Code Online (Sandbox Code Playgroud)
if my_script.py是一个打算运行的脚本python my_script.py.
但是,my_module.py应该运行python模块python -m my_module.甚至包含相对导入的脚本也应该运行python -m.我怎么能python -m my_module在pdb控制下运行?以下不起作用:
python -m pdb -m my_module
Run Code Online (Sandbox Code Playgroud)
ffe*_*ast 15
你现在不能这样做,因为-m终止选项列表
python -h
...
-m mod : run library module as a script (terminates option list)
...
Run Code Online (Sandbox Code Playgroud)
这意味着解释其余参数列表是mod的工作,这种行为完全取决于内部如何设计mod以及它是否支持另一个-m
让我们看看里面有什么发生PDB的蟒蛇2.x的.实际上,没有任何东西,只需要提供一个脚本名称:
if not sys.argv[1:] or sys.argv[1] in ("--help", "-h"):
print "usage: pdb.py scriptfile [arg] ..."
sys.exit(2)
mainpyfile = sys.argv[1] # Get script filename
if not os.path.exists(mainpyfile):
print 'Error:', mainpyfile, 'does not exist'
sys.exit(1)
del sys.argv[0] # Hide "pdb.py" from argument list
# Replace pdb's dir with script's dir in front of module search path.
sys.path[0] = os.path.dirname(mainpyfile)
# Note on saving/restoring sys.argv: it's a good idea when sys.argv was
# modified by the script being debugged. It's a bad idea when it was
# changed by the user from the command line. There is a "restart" command
# which allows explicit specification of command line arguments.
pdb = Pdb()
while True:
try:
pdb._runscript(mainpyfile)
Run Code Online (Sandbox Code Playgroud)
对于当前发布的python 3.x版本也是如此
允许做你所要求的拉动请求已在5天前合并.多么神秘的巧合啊!这是代码
所以只需等待即将到来的python 3.x版本就可以解决这个问题了)
Python 3.7 添加了该功能
从docs,看起来你的命令:
python -m pdb -m my_module
Run Code Online (Sandbox Code Playgroud)
将开始在 Python 3.7 上工作:
3.7 版中的新功能:pdb.py 现在接受一个 -m 选项,该选项执行类似于 python3 -m 的方式的模块。与脚本一样,调试器将在模块的第一行之前暂停执行。
如果在运行模块时发生异常,以下脚本将运行一个模块并进入事后调试。它应该适用于 Python 2.7 和 3.x。
用法:
mdb.py module_name [args ...]
Run Code Online (Sandbox Code Playgroud)
已知限制:
sys.argv[0]会保留为模块名称,而不是解析为模块的文件路径。数据库文件
#!/usr/bin/env python
from __future__ import print_function
import pdb
import runpy
import sys
import traceback
if len(sys.argv) == 0:
print("Usage: mdb.py module_name [args ...]")
exit(1)
modulename = sys.argv[1]
del sys.argv[0]
try:
runpy.run_module(modulename, run_name='__main__')
except:
traceback.print_exception(*sys.exc_info())
print("")
print("-" * 40)
print("mdb: An exception occurred while executing module ", modulename)
print("mdb: See the traceback above.")
print("mdb: Entering post-mortem debugging.")
print("-" * 40)
pdb.post_mortem(sys.exc_info()[2])
Run Code Online (Sandbox Code Playgroud)
示范:
$ tree
.
??? mdb.py
??? mypackage
??? __init__.py
??? __main__.py
??? mymodule.py
1 directory, 4 files
$ ###################### Examine the module code ###################
$ cat mypackage/mymodule.py
from __future__ import print_function
import sys
print("mymodule loaded")
if __name__ == "__main__":
print("mymodule executed")
print("args:", sys.argv)
$ #################### Run the module through python ###############
$ python -m mypackage.mymodule abc defgh
mymodule loaded
mymodule executed
args: ['/home/leon/playground/mdb/mypackage/mymodule.py', 'abc', 'defgh']
$ #################### Run the module through mdb ##################
$ ./mdb.py mypackage.mymodule abc defgh
mymodule loaded
mymodule executed
args: ['mypackage.mymodule', 'abc', 'defgh']
$ ### ^^^^^^^^^^^^^^^^^^
$ ### Note that sys.argv[0] is not resolved to the file path
$ ###################### Examine the module code ###################
$ cat mypackage/__main__.py
from __future__ import print_function
import sys
print("mypackage loaded")
if __name__ == "__main__":
print("mypackage executed")
print("args:", sys.argv)
print(x + y)
$ #################### Run the module through python ###############
$ python -m mypackage
mypackage loaded
mypackage executed
args: ['/home/leon/playground/mdb/mypackage/__main__.py']
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/home/leon/playground/mdb/mypackage/__main__.py", line 9, in <module>
print(x + y)
NameError: name 'x' is not defined
$ #################### Run the module through mdb ##################
$ ./mdb.py mypackage
mypackage loaded
mypackage executed
args: ['mypackage']
Traceback (most recent call last):
File "./mdb.py", line 17, in <module>
runpy.run_module(modulename, run_name='__main__')
File "/usr/lib/python2.7/runpy.py", line 192, in run_module
fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/home/leon/playground/mdb/mypackage/__main__.py", line 9, in <module>
print(x + y)
NameError: name 'x' is not defined
----------------------------------------
mdb: An exception occurred while executing module mypackage
mdb: See the traceback above.
mdb: Entering post-mortem debugging.
----------------------------------------
> /home/leon/playground/mdb/mypackage/__main__.py(9)<module>()
-> print(x + y)
(Pdb) q
Run Code Online (Sandbox Code Playgroud)
正如其他人所说,这个功能是在Python 3.7中添加的。然而,人们仍在使用旧版本,所以希望下面的解决方案可以帮助那些人!
__main__.py基本上,您只需导入包的文件即可创建运行该模块的脚本:
# runner.py
import path.to.my.module.__main__
Run Code Online (Sandbox Code Playgroud)
然后只需在 pdb: 下运行该脚本即可python -m pdb runner.py [args]。
该解决方案适用于相对导入(因为__main__在包路径下运行而不是作为脚本调用)。
之所以只需要导入__main__模块,是因为Python导入会触发顶层代码的执行,并且__main__逻辑是在顶层执行的。
| 归档时间: |
|
| 查看次数: |
12718 次 |
| 最近记录: |