Netbeans Python 调试,郁闷的包导入问题

这几天在帮忙开发一个 python 项目。使用 netbeans 的时候,遇到一个诡异的问题。

如果使用“运行”来跑项目,一切正常。而如果使用“调试”来跑项目,当执行到 import 第三方的库的时候,就会产生“ImportError: No module named xxxx”。郁闷不已,上网查了半天,没找到可用的信息。

毛主席教育我们“自己动手,丰衣足食”。于是就祭出“观察、归纳和总结”的科学的研究方法,对这个灵异现象进行了一番探索。

出现导入问题的包都是用了 egg 打包的第三方包。在我的系统中,这几个包都是放在/usr/local/lib/python2.6/dist-packages/下。在命令行能正常执行,在 netbeans 中直接执行也无异常。说明包本身的安装没有问题。那么 netbeans 调试就出现找不到这个包,是不是 netbeans 的调试环境有什么特殊呢?看了一下 netbeans 的调试窗口,发现这个脚本~/.netbeans/6.7/config/nbPython/debug/nbpythondebug/jpydaemon.py。很明显,这个是 netbeans 为了集成调试功能而开发的一个 python 调试器。难道是这个netbeans自带的调试器的问题?祭出 sys.path 一看,果然正常执行的时候,dist-packages 下的 egg 包都被放到搜索路径里。而调试的时候,没有一个 egg 包在 sys.path 中。而是多了一些 netbeans 使用的目录而已。

郁闷啊,为什么调试器不能直接继承系统环境呢?

于是乎,将每个 egg 包都手工加入 Python Platforms 的 Python Path 里。问题解决了。可以带第三方 egg 包来调试项目了。

虽然问题解决了,不过还是不爽,如果我一个项目要是有 n 个 egg 包,那不是要每个都设置一下?

Hacking……

发现 jpydaemon.py 的 1588 行修改了sys.path,导致默认的路径信息丢失。

pythonPath = dbgutils.PythonPathHandler(None)
pythonPath.getPyPathFromEnv()

再检查 dbgutils.py ,原来 netbeans 的调试环境只读取了环境变量 PYTHONPATH,未添加默认的 sys.path。而我并没有使用 PYTHONPATH 环境变量,所以导致一些安装好的包无法导入。164 行直接覆盖了 sys.path。

    def getPyPathFromEnv( self ):
        "PYTHONPATH env and set sys.path out of it "
        pyPath = os.environ["PYTHONPATH"]
        # cleanly take care of previous ';' convention
        if os.pathsep != ';':
            pyPath.replace(';' , os.pathsep)
        if pyPath.find(os.pathsep) != -1:
            sys.path = pyPath.split(os.pathsep)
            # remove empty nodes first
            for element in sys.path:
                if ( len(element.strip())==0 ):
                    sys.path.remove(element)

修改 164 行

sys.path = pyPath.split(os.pathsep) + sys.path

这个世界又清爽了……

不知道会不会有什么问题。有问题,继续 fix 好了。

Join the Conversation

4 Comments

  1. 能用import导入
    但是 我在导入后调用属性就不行了,比如(memcache.Client)
    很奇怪 在终端下性 ,在netbeans下就说
    AttributeError: ‘module’ object has no attribute ‘Client’

Leave a comment

Your email address will not be published. Required fields are marked *