【问题标题】:How to debug a python module that needs to be executed with -m?如何调试需要使用-m执行的python模块?
【发布时间】:2014-01-11 16:11:42
【问题描述】:

我在那里试用的每个调试器都需要一个源文件来调试。然而 Python 并不总是以这种方式工作。

我有一个模块,它是一个文件夹,其中包含 __init__.py__main__.py 文件等,我通常这样执行:

$ cd /parent/folder
$ python3 -m module_folder --help

如果我不使用-m,则相对导入会失败。如果我只是将文件夹传递给pudbpdb 等,调试器会失败:

$ cd /parent/folder
$ python3 -m pdb module_folder
Traceback (most recent call last):
  File "/usr/lib64/python3.3/pdb.py", line 1658, in main
    pdb._runscript(mainpyfile)
  File "/usr/lib64/python3.3/pdb.py", line 1536, in _runscript
    with open(filename, "rb") as fp:
IsADirectoryError: [Errno 21] Is a directory: 'module_folder'
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /usr/lib64/python3.3/pdb.py(1536)_runscript()
-> with open(filename, "rb") as fp:
(Pdb)

我该如何调试呢?最好使用pudb,并且不删除相关导入。

【问题讨论】:

  • 如果有人能找到一种不需要修改程序源和不需要更改工作目录的方法来实现这一点,那就太好了。

标签: python debugging command-line relative-import pudb


【解决方案1】:

把它放在__main__.py的顶部:

#!/usr/bin/env python3

# Declare itself as package if needed
if __name__ == '__main__' and __package__ is None:
    import os, sys, importlib
    parent_dir = os.path.abspath(os.path.dirname(__file__))
    sys.path.append(os.path.dirname(parent_dir))
    __package__ = os.path.basename(parent_dir)
    importlib.import_module(__package__)

# Continue with your code
do_things()

这样,这两个命令就变得等价了:

  1. cd /parent/folder; python -m module_folder
  2. python /parent/folder/module_folder/__main__.py

只需使用第二种语法进行调试:

pudb /parent/folder/module_folder/__main__.py

python3 -m pdb /parent/folder/module_folder/__main__.py

这同样适用于 Python 2。

您可以安全地从上面的代码中删除__name__ == '__main__' and 部分,因为正如您在__main__.py 中所写的那样,它始终是True。但是,这是一种常见的做法。请参阅PEP 366this other answer

【讨论】:

    【解决方案2】:

    我想你想这样做:

    $ cd /parent/folder
    $ python3 -m pdb -m module_folder
    

    事实上,您错过了第二个 -m,这让 Python 认为 module_folder 是要运行的脚本的名称。

    【讨论】:

    • 这就是我想做的,但上面写着getopt.GetoptError: option -m not recognized
    • 这是一个非常新的功能,仅适用于 python ~ 3.7 或更高版本:github.com/python/cpython/pull/4752
    • @user:我不这么认为,因为我在 2013 年写了这个答案,当时 Python 3.7 还不存在。或者,也许这个答案可以预见未来 5 年?
    • 很简单,他们看到了你的答案并复制了它。当我尝试用 CPython 3.6 回答时,它抛出了这个错误getopt.GetoptError: option -m not recognized。但是当我升级到 Python 3.7.2 时,它运行良好。
    猜你喜欢
    • 2018-02-26
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2014-10-08
    • 2019-06-19
    • 1970-01-01
    • 2019-05-22
    • 1970-01-01
    相关资源
    最近更新 更多