【问题标题】:What else can I do to troubleshoot a package not importing in python yet imports in ipython while in a virtualenv?我还能做些什么来解决在 virtualenv 中未在 python 中导入但在 ipython 中导入的包?
【发布时间】:2014-08-30 23:40:16
【问题描述】:

我是一名 Python 爱好者,我决定认真地创建一些我自己的可重用包。

我的问题概要:

  1. 调用python test_dummy.py 无法导入包eforest。引发 ImportError。
  2. import eforest 在 python 解释器和 ipython 解释器中都不会抛出异常。
  3. ipython 解释器中调用 run test_dummy.py 不会引发异常。
  4. 所有案例都在 virtualenv 中运行。

virtualenv 与我的问题无关。我发布了一个新问题:script that adds packages to sys.path import as expected when run from ipython but throw exception when the script is run from python

Can't import package from virtualenv也有类似的问题

我阅读了 virtualenvvirtualenvwrapper 上的文档,并将它们都安装在带有 Python 2.7.6 的 Ubuntu 14.04.1 LTS 系统上。

我创建了一个虚拟环境:

mkvirtualenv module_troubleshooting -a . -r requirements.txt

包含我的requirements.txt 文件:

Django==1.6.6
EasyProcess==0.1.6
PyVirtualDisplay==0.1.5
South==1.0
argparse==1.2.1
ipython==2.2.0
lxml==3.3.5
selenium==2.42.1
wsgiref==0.1.2

我用workon module_troubleshooting激活了我的virtualenv

我的 virtualenv 处于活动状态:(module_troubleshooting)dmmmd@ubuntuG5:

我从 virtualenvwrapper 文档中了解到,我可以通过 add2virtualenv 命令将包添加到 sys.path。

使用add2virtualenv 我添加了我创建的非常简单的包。我确认 pth 文件确实包含这些包。

/home/dmmmd/development/python/singleton
/home/dmmmd/development/python/display
/home/dmmmd/development/python/browser
/home/dmmmd/development/python/eforest
/home/dmmmd/development/python/dummy

我跑了ipython 看看我是否可以导入这些包。我可以。没有错误。检查 ipython 中的sys.path 发现上述路径存在。

为了我自己的启迪,我制作了以下名为 test_dummy.py 的模块:

import browser
import display
import singleton
import eforest

我在 ipython 中运行了以下命令:run test_dummy.py

ipython 中没有例外。

然后我退出 ipython 并运行以下命令以确保自己没有调用全局 python 并查看 python 是否会运行脚本:/home/dmmmd/.virtualenvs/module_troubleshooting/bin/python test_dummy.py

Traceback (most recent call last):
    File "tests/test_dummy.py", line 4, in <module>
import eforest
ImportError: No module named eforest

按预期导入其他三个包,浏览器、显示器和单例,并在 import eforest

处引发异常

起初,我推测 eforest 可能包含一些异常。所以我运行了/home/dmmmd/.virtualenvs/module_troubleshooting/bin/python,在导入 eforest 时出现了预期的提示并且没有导入错误:

Python 2.7.6 (default, Mar 22 2014, 22:57:26)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import eforest
>>> print eforest
<module 'eforest' from 'eforest/__init__.pyc'>
>>>

然后我推测 ipython 和 python 的 sys.path 可能不同。我将 python 的 sys.path 保存到一个文件中并将其编辑为以下内容,以便可以导入来自 sys.path 的列表:

/home/dmmmd/.virtualenvs/module_troubleshooting/bin/python -c "import sys; print sys.path" > path.py

我编辑了 path.py 以便 from path import path 成为列表 sys.path 来自调用 /home/dmmmd/.virtualenvs/module_troubleshooting/bin/python

然后我运行 ipython 并输入以下命令:

In [1]: from path import path

In [2]: path # this is the sys.path from calling /home/dmmmd/.virtualenvs/module_troubleshooting/bin/python
Out[2]:
['',
 '/home/dmmmd/development/python/singleton',
 '/home/dmmmd/development/python/eforest',
 '/home/dmmmd/development/python/dummy',
 '/home/dmmmd/development/python/display',
 '/home/dmmmd/development/python/browser',
 '/home/dmmmd/.virtualenvs/module_troubleshooting/lib/python2.7',
 '/home/dmmmd/.virtualenvs/module_troubleshooting/lib/python2.7/plat-powerpc-linux-gnu',
 '/home/dmmmd/.virtualenvs/module_troubleshooting/lib/python2.7/lib-tk',
 '/home/dmmmd/.virtualenvs/module_troubleshooting/lib/python2.7/lib-old',
 '/home/dmmmd/.virtualenvs/module_troubleshooting/lib/python2.7/lib-dynload',
 '/usr/lib/python2.7',
 '/usr/lib/python2.7/plat-powerpc-linux-gnu',
 '/usr/lib/python2.7/lib-tk',
 '/home/dmmmd/.virtualenvs/module_troubleshooting/local/lib/python2.7/site-packages',
 '/home/dmmmd/.virtualenvs/module_troubleshooting/lib/python2.7/site-packages']

要查看 ipythonsys.path 是否不同,我输入了:

In [5]: import sys

In [6]: len(sys.path)
Out[6]: 19

In [7]: len(path)
Out[7]: 16

In [8]: [item for item in sys.path if item not in path]
Out[8]:
['/home/dmmmd/.virtualenvs/module_troubleshooting/bin',
 '/home/dmmmd/.virtualenvs/module_troubleshooting/local/lib/python2.7/site-packages/IPython/extensions',
 '/home/dmmmd/.ipython']

ipython 的 sys.path 的最后两项与 ipython 相关。一个不同的项目是“/home/dmmmd/.virtualenvs/module_troubleshooting/bin”。

谁能提供任何其他故障排除建议或向我解释如何在 ipython 的 sys.path 中包含 '/home/dmmmd/.virtualenvs/module_troubleshooting/bin'允许 eforest 在调用 run test_dummy.py 时按预期在 ipython 中导入?

eforest 包:

eforest/
├── CustomElementFilters.py
├── CustomEtrees.py
├── CustomEtrees.pyc
├── __init__.py
└── __init__.pyc

同样,eforest 在 ipython 和 python 解释器中按预期导入,但是当脚本作为参数传递给 /home/dmmmd/.virtualenvs/module_troubleshooting/bin/python test_dummy.py 时它不会导入。

我想到的与其他软件包不同的唯一可能的 eforest 例外是它导入了 lxml。 lxml 能否以某种方式依赖于 sys.path 中的 '/home/dmmmd/.virtualenvs/module_troubleshooting/bin'

我们将不胜感激任何有关故障排除的建议。我在使用 py.test 时首先注意到了这个问题。我认为它与 py.test 有关,但事实证明我正在编写的测试脚本也没有使用 python 运行。我决定停下来看看能不能得到一些帮助。

排除 virtualenv 作为问题来源

我使用 python test_dummy.py 运行了以下脚本,并使用了 advisornv deactivated

import sys
import os
HOME = os.path.expanduser('~')
PYTHON = os.path.join(HOME, 'development/my_python')
PACKAGES = [
    'browser',
    'display',
    'singleton',
    'eforest'
]
for package in PACKAGES:
    package = os.path.join(PYTHON, package)
    if os.path.exists(package) is True:
        if package not in sys.path:
            print "loading package '{0}'".format(package)
            sys.path.append(package)
        else:
            print "package '{0}' already in sys.path".format(package)
    else:
        raise
import browser
import display
import singleton
import eforest

使用 virtualenv deactivated eforest 是唯一不通过运行python test_dummy.py 命令导入的包。

结果:

Traceback (most recent call last):
  File "my_django/automated_browsing/tests/test_dummy.py", line 16, in <module>
import eforest
ImportError: No module named eforest

【问题讨论】:

    标签: python ipython virtualenv ubuntu-14.04 virtualenvwrapper


    【解决方案1】:

    我找到了一个解决方案,尽管该解决方案没有解决为什么在使用python test_dummy.py 运行脚本时不导入以ad hoc 方式添加到sys.path 的某些包路径的问题。

    我最初在尝试使用 py.test 时遇到了这个问题。 In the py.test documentation I saw this tip 关于“使用virutalenv、pip 和可编辑模式管理您的项目。”我忽略了它,因为我认为它对于我的 Python 知识水平来说太高级了。

    在阅读了“creating your own python project”之后,我决定试试这个技巧。

    在密码中,我使用以下代码创建了一个setup.py 文件:

    from setuptools import setup, find_packages
    
    setup(name='import_troubleshooting', version='1.0')
    packages = find_packages(exclude=[
        'my_django',
        'fake*',
        'tests*'
    ])
    

    然后我在命令行执行了以下代码:

    pip install -e .  # the pip way (which just calls "setup.py develop")
    

    然后我执行了以下代码,得到了预期的结果:

    $ python tests/test_dummy.py
    # output    
    package '/home/dmmmd/development/my_python/browser' already in sys.path
    package '/home/dmmmd/development/my_python/display' already in sys.path
    package '/home/dmmmd/development/my_python/singleton' already in sys.path
    loading package '/home/dmmmd/development/my_python/test_a'
    loading package '/home/dmmmd/development/my_python/hello_world'
    loading 'browser'
    loading 'display'
    loading 'singleton'
    loading 'test_a'
    loading 'hello_world.hello'
    Hello, world!
    

    这些都没有向我解释为什么我不能以 ad hoc 方式添加包路径。然而,我很高兴学到了一些关于 python 安装和打包的知识。从python tests/test_dummy.py 调用时,test_dummy.py 脚本现在可以按预期运行。

    我现在很困惑为什么在运行test_dummy.py 脚本时其中三个包已经在sys.path 中:

    package '/home/dmmmd/development/my_python/browser' already in sys.path
    package '/home/dmmmd/development/my_python/display' already in sys.path
    package '/home/dmmmd/development/my_python/singleton' already in sys.path
    

    我不记得做过任何将这些添加到sys.path 的事情,但这是可能的,因为我一直在做各种教程。在我没有运行我创建的setup.py 的任何其他环境中,它们不在sys.path 中。

    我的困惑是 Python 复杂性的症状,而不是原因!

    感谢大家的意见。

    注意:这是 python test_dummy.py 在新的 virtualenv 之后的输出:

    $ pip install -e .
    # install output unremarkable
    $ python tests/test_dummy.py
    # output
    loading package '/home/dmmmd/development/my_python/automated_browsing/browser'
    loading package '/home/dmmmd/development/my_python/automated_browsing/display'
    loading package '/home/dmmmd/development/my_python/automated_browsing/singleton'
    loading package '/home/dmmmd/development/my_python/automated_browsing/hello_world'
    loading package '/home/dmmmd/development/my_python/automated_browsing/test_a'
    loading 'browser'
    loading 'display'
    loading 'singleton'
    loading 'hello_world.hello'
    Hello, world!
    loading 'test_a'
    

    【讨论】:

      猜你喜欢
      • 2017-05-04
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多