在Emacs中使用当前虚拟环境的Python进程调试pdb

23 投票
4 回答
5536 浏览
提问于 2025-04-16 04:16

我在用Emacs调试一些Python代码,使用的是pdb,但遇到了一些导入的问题。我的依赖库安装在一个我自己设置的虚拟环境里。

但是,pdb偏偏使用的是/usr/bin/python,而不是我虚拟环境里的Python。

我用virtualenv.el来支持在Emacs中切换环境,并通过一些后激活的钩子来实现,具体可以参考这篇文章:

http://jesselegg.com/archives/2010/03/14/emacs-python-programmers-2-virtualenv-ipython-daemon-mode/

在运行M-x python-shell时,这个方法效果很好。

>>> import sys
>>> print sys.path 

这指向了我所有虚拟环境的库,表明python-shell确实是我虚拟环境里的。

但是,M-! which python却给出了/usr/bin/python,这就和之前的结果矛盾了。

有没有人知道我该如何让M-x pdb使用当前激活的虚拟环境里的Python进程呢?

4 个回答

2

可能你的 pdb 命令是和某个特定版本绑定在一起的。

$ ls -ald /usr/bin/pdb
lrwxrwxrwx 1 root root 6 Jun  2 23:02 /usr/bin/pdb -> pdb2.6

接着,看看 pdb2.6 的第一行。它包含了

#! /usr/bin/python2.6

这就是为什么 pdb 总是很固执,似乎总是在某个特定版本的 Python 下运行。因为它确实是这样!实际上,这种依赖关系对于像符号调试器这样的软件来说是有道理的。

我从源代码编译了 python2.7,但显然没有找到 pdb。经过仔细检查,我在 lib 文件夹下找到了 python-2.7 的 pdb.py。

为了方便,我为它创建了一些符号链接:

$ cd /opt/python-dev   ##-- this is where I installed from sources
$ cd bin
$ sudo ln -s ../lib/python2.7/pdb.py pdb2.7
$ sudo ln -s pdb2.7 pdb

现在观察 pdb2.7 的第一行。它写着:

#! /usr/bin/env python

... 这看起来比之前的版本要好。它基本上意味着 pdb 将在你环境中定义的当前 Python 下启动,无论是什么,而不是像 /usr/bin/python/usr/bin/python2.6 这样的硬编码路径。知道这一点真不错!

我还从系统文件中删除了 pdbpdb2.6,因为我更喜欢在 virtualenv 中进行开发和调试。这样做的话,我就不会再被同样的把戏所困扰了。

希望这对你有帮助。

19

这样调用 pdb:

python -m pdb myscript.py

而不是这样:

pdb myscript.py
8

python-shell 使用一个叫 python-default-interpreter 的变量来决定用哪个 Python 解释器。当这个变量的值是 cpython 时,它会查看另外两个变量 python-python-commandpython-python-command-args 来确定要使用的解释器和参数。这两个变量是通过 virtualenv.el 来设置当前的虚拟环境的。

所以,当你使用 python-shell 命令时,它会毫无问题地使用你的虚拟环境。

但是,当你输入 M-! python 时,你并没有使用 python-python-commandpython-python-command-args 这两个变量。因此,它会使用在你的路径中找到的 Python 工具。

当你调用 M-x pdb 时,它会使用 gud-pdb-command-name 作为默认的 pdb 工具。如果你想重新定义这个变量,每次激活环境时可以这样做:

(defadvice virtualenv-activate (after virtual-pdb)
  (custom-set-variables
     '(gud-pdb-command-name
        (concat virtualenv-active "/bin/pdb" ))))

(ad-activate 'virtualenv-activate)

要在你的虚拟环境中使用 pdb,请执行以下操作:

cp /usr/bin/pdb /path/to/virtual/env/bin

然后编辑 /path/to/virtual/env/bin/pdb 的第一行,使其变为:

#! /usr/bin/env python

重新激活你的环境,Pdb 现在应该会使用你的虚拟环境中的 Python,而不是系统全局的 Python。

撰写回答