setup.py之后的Python ImportError

时间:2016-01-08 20:26:06

标签: python pip python-import easy-install

使用setup.py安装我的python项目并在终端中执行后,我收到以下错误:

...
from ui.mainwindow import MainWindow
  File "/usr/local/lib/python2.7/dist-packages/EpiPy-0.1-py2.7.egg/epipy/ui/mainwindow.py", line 9, in <module>
    from model.sir import SIR
ImportError: No module named model.sir

...

我们假设我们的项目cookies具有以下结构:

.
├── setup.py
└── src
    ├── a
    │   ├── aa.py
    │   └── __init__.py
    ├── b
    │   ├── bb.py
    │   └── __init__.py
    ├── __init__.py
    └── main.py

档案:cookies/src/main.py

from a import aa

def main():
    print aa.get_aa()

档案cookies/src/a/aa.py

from b import bb

def get_aa():
    return bb.get_bb()

档案:cookies/src/b/bb.py

def get_bb():
    return 'bb'

档案:cookies/setup.py

#!/usr/bin/env python

import os
import sys

try:
    from setuptools import setup, find_packages
except ImportError:
    raise ImportError("Install setup tools")

setup(
    name = "cookies",
    version = "0.1",
    author = "sam",
    description = ("test"),
    license = "MIT",
    keywords = "test",
    url = "asd@ads.asd",
    packages=find_packages(),
    classifiers=[
    """\
    Development Status :: 3 - Alpha
    Operating System :: Unix
    """
    ],
    entry_points = {'console_scripts': ['cookies = src.main:main',],},
)

如果我将cookies作为root安装$ python setup.py install并执行cookies,则会收到以下错误:ImportError: No module named b。我该如何解决这个问题。

2 个答案:

答案 0 :(得分:4)

我要做的是到处使用绝对导入(来自epipy import ...)。这是PEP 328中推荐的内容。

如果未安装项目,您的导入将不再有效。您可以将项目目录添加到PYTHONPATH,安装软件包,或者在我开发软件包的过程中我做的事情install with the 'editable' optionpip install -e

在可编辑模式下,不是在python发行版中安装包代码,而是创建指向项目的指针。这样它是可导入的,但是程序包在开发中使用实时代码。

示例:

我正在/ home / jbchouinard / mypackage中开发一个包。在我的代码中,我使用绝对导入,例如from mypackage import subpackage

如果我使用pip install安装,该软件包将安装在我的发行版中,请在/usr/lib/python2.7/dist-packages中说明。如果我对软件包进行了进一步的更改,我必须升级或卸载/重新安装软件包。这很快就会变得乏味。

如果我使用pip install -e安装,则会在/usr/lib/python2.7/dist-packages中创建一个指针(.pth文件),指向/ home / jbchouinard / mypackage。我可以import mypackage就像它正常安装一样,但使用的代码是/ home / jbchouinard / mypackage中的代码;任何变化都会立即反映出来。

答案 1 :(得分:1)

我的一个项目遇到了类似的问题。 我已经能够通过在我的模块的开头添加这一行来解决我的问题(除了sys&amp; os之前的所有导入,这是此插入所需的),因此它将包括父文件夹,并且它将能够看到父文件夹(事实证明它默认不这样做):

import sys
import os
sys.path.insert(1, os.path.join(sys.path[0], '..'))
# all other imports go here...

这样,你的main.py将包含父文件夹(epipy)。 尝试一下,希望这会有所帮助: - )