使用PyCharm调试Popen子进程

16

我正在尝试调试一个使用psutil.Popen对象的Python应用程序。当我启动一个子进程时,PyCharm将我的命令行替换为以下内容:

python -m pydevd.py --multiproc --client 127.0.0.1 --port 52581 --file <myapplication>

最终导致出现错误:

python.exe: Import by filename is not supported.

如果我不使用-m选项启动相同的命令,一切似乎都很好。有没有办法改变PyCharm的调试器启动命令?

我已经升级到了PyCharm社区版4.0.3,并且新的调试器命令类似于:

python.exe "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0.3\helpers\pydev\pydevd.py" 
--multiproc --client 127.0.0.1 --port 62661 
--file __main__.py local -c local.yml -f input/11_12.xls

-c-f是我的模块命令行参数。调试器启动命令已更改,但未解决此问题;我仍然会遇到Import by filename is not supported错误。

代码示例可在Bitbucket.org找到。 Pycharm的运行配置应如下:

Script:            __main__.py
Script parameters: server
Working directory: %path to the repository%

这是一个棘手的问题。我需要再仔细看看。 - Games Brainiac
<myapplication> 是什么样子?它只是一个名称还是完整路径?如果是完整路径,请尝试将其更改为仅名称,并确保父文件夹在 sys.path 中。与 https://dev59.com/qW3Xa4cB1Zd3GeqPfoeq 进行比较。 - Piotr Dobrogost
面对使用社区版 3.4(以及我 Python 开发的第二天)出现了同样的问题。有人可以评论一下以前的版本是否能够正常工作吗? - Prabhjot
@Prabhjot 来自 https://www.jetbrains.com/pycharm/webhelp/python-debugger.html - 在调试时自动附加到子进程:如果选中此复选框,则PyCharm将自动附加正在调试的进程的所有子进程。因此,如果父进程有子进程,则它们的断点始终有效。 该功能已经在PyCharm 2.7中可用(甚至可能在2.7之前就可用)。 - Piotr Dobrogost
@yole https://bitbucket.org/lgyanf/pycharm-multiprocess-debug - Ivan Gromov
显示剩余4条评论
1个回答

19

正如Piotr所提到的,PyCharm有“在调试时自动附加到子进程”的功能。如果该子进程是Python进程,PyCharm调试器将更改该进程的启动参数(请参见源代码中的patch_args函数)。当您以这种方式启动子进程时:

args = ['python',
        '-m', 'pycharm-multiprocess-debug',
        'worker']
worker = subprocess.Popen(args)

实际的启动命令如下:

python.exe -m "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 4.0.3\helpers\pydev\pydevd.py"
--multiproc --client 127.0.0.1 --port 62661
--file pycharm-multiprocess-debug

事情出了差错。我可以找到几个解决方法:

  1. 如果您不需要调试子进程,最简单的方法就是在PyCharm设置中关闭“自动附加到调试子进程”

  2. 将您的args更改为:

    args = ['python', '__main__.py', 'worker']
    

    缺点是你只能运行Python文件,而不能运行Python模块。

  3. 对于Python子进程,我推荐最后一种解决方案:

  4. from multiprocessing import Process
    
    def server():
        p = Process(target=worker)
        p.start()
        print 'worker pid: {}'.format(p.pid)
        p.join()
    

我应该在哪里写这段代码?? args = ['python', 'main.py', 'worker'] - Marco Sanchez
@MARCO,args 在 Ivan 的代码示例中:https://bitbucket.org/lgyanf/pycharm-multiprocess-debug/src/973bebe2e1c249ff75f5db1e8ddaad0720a0dec5/__main__.py?at=default - ZZY
我的当前命令(无法附加Pycharm调试器)如下所示:subprocess.Popen("cd /users/lewis/; ENV_VAR=99; python main.py") - user3180
1
@user3180你没有提到shell=True,但很明显,你尝试运行一个shell命令序列。如果使用shell=True,子进程调试将无法工作。需要运行的程序应该是'python'(我建议使用sys.executable代替'python',这样可以确保它与父进程是同一个Python版本)。在你的情况下,你还需要传递cwdenv参数。 - Adrian W

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接