Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
启动Python调试器,同时以脚本形式执行模块_Python_Pdb - Fatal编程技术网

启动Python调试器,同时以脚本形式执行模块

启动Python调试器,同时以脚本形式执行模块,python,pdb,Python,Pdb,在开发Python包时,使用-m选项将包内的模块作为脚本运行以进行快速测试非常方便。例如,对于包含模块somemodule.py的somepackage,调用 python -m somepackage.somemodule 从somepackage所在的目录中,将运行somemodule.py,就像子模块是\uuuuuu main\uuuu一样。如果包使用如上所述的显式相对导入,则使用此调用语法尤其重要 类似地,使用-m选项调试脚本也很方便,如中所示 python -m pdb somesc

在开发Python包时,使用
-m
选项将包内的模块作为脚本运行以进行快速测试非常方便。例如,对于包含模块
somemodule.py
somepackage
,调用

python -m somepackage.somemodule
somepackage
所在的目录中,将运行
somemodule.py
,就像子模块是
\uuuuuu main\uuuu
一样。如果包使用如上所述的显式相对导入,则使用此调用语法尤其重要

类似地,使用
-m
选项调试脚本也很方便,如中所示

python -m pdb somescript.py

有没有办法同时做到这两个方面?也就是说,我可以像调用脚本一样调用模块并同时启动调试器吗?我意识到我可以进入代码本身并插入
importpdb;pdb.set_trace()
在我想中断的地方,但我正试图避免这种情况。

经过一段时间的试验,结果证明这种方法确实有效:

python -c "import runpy; import pdb; pdb.runcall(runpy.run_module, 'somepackage.somemodule', run_name='__main__')"

出于某种原因,在
pdb.run
上使用
pdb.runcall
是很重要的。

这里还有另一个选项也适用于命令行参数

通常最好将脚本的逻辑封装在
main
函数中。然后,您可以让
main
接受可选的参数列表,以覆盖
sys.argv
。下面是一个名为
argdemo.py
的示例:

def main(cmd_line_args=None):
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument("number", help="a number", type=int)

    # allow cmd_line_args to override sys.argv
    if cmd_line_args is None:
        args = parser.parse_args()
    else:
        args = parser.parse_args(cmd_line_args)

    print("The number is {}".format(args.number))

if __name__ == '__main__':
    main()
此模块可以正常运行:

$ python -m argdemo 2
> The number is 2
也可以通过直接调用
main()
使用
pdb
运行:

$ python -c "import pdb; import argdemo; pdb.runcall(argdemo.main, ['2'])"
(Pdb) continue
> The number is 2
(注意,
cmd\u line\u args
必须是字符串列表,就像
argv
一样)


作为额外的好处,当您的模块具有可导入的
main
函数时,您可以用相同的方式为其编写单元测试=)

基于@jed的答案,我构建了这个模块:

import pdb
import runpy
import sys


def main():
    module = sys.argv[1]
    sys.argv[1:] = sys.argv[2:]
    pdb.runcall(runpy.run_module, module, run_name='__main__')


__name__ == '__main__' and main()
将该模块作为
mpdb.py
放在Python路径中的任何位置(当前目录有效),然后可以调用:

python -m mpdb somepackage.somemodule even with args
在Python中有很多方法可以解决这个问题。与Python 3.7类似,您可以执行以下操作:

python -m pdb -m somepackage.somemodule
我还提供了较旧的Python版本(2.7+):

这对我很有用(将python模块作为带有-m选项的脚本进行调试)

我造成了一个划痕

import runpy

if __name__ == '__main__':
    runpy.run_module('somepackage.somemodule', run_name="__main__", alter_sys=True)

这个想法来自:

pdb.run需要一个字符串,而不是一个可调用的字符串
python-c“import runpy;import pdb;pdb.run(\”runpy.run\u模块('somepackage.somemodule',run\u名称=''''''''\')”)”
同样有效,但更麻烦
import runpy

if __name__ == '__main__':
    runpy.run_module('somepackage.somemodule', run_name="__main__", alter_sys=True)