Python没有找到模块

时间:2013-11-14 08:18:57

标签: python python-import

给出以下python项目,在PyDev中创建:

├── algorithms
│   ├── __init__.py
│   └── neighborhood
│       ├── __init__.py
│       ├── neighbor
│       │   ├── connector.py
│       │   ├── __init__.py
│       │   ├── manager.py
│       │   └── references.py
│       ├── neighborhood.py
│       ├── tests
│       │   ├── fixtures
│       │   │   └── neighborhood
│       │   ├── __init__.py
│       └── web
│           ├── __init__.py
│           └── service.py
├── configuration
│   ├── Config.py
│   └── __init__.py
├── __init__.py
└── webtrack
    |- teste.py
    ├── .gitignore
    ├── __init__.py
    ├── manager
        ├── Data.py
        ├── ImportFile.py
        └── __init__.py

我们一直在尝试将模块从一个文件夹导入到另一个文件夹,例如:

from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector

产生结果:

Traceback (most recent call last):
File "teste.py", line 49, in <module>
from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector
ImportError: No module named algorithms.neighborhood.neighbor.connector

我们尝试将其路径附加到sys.path变量但没有成功。

我们还尝试使用os.walk将所有路径插入到PATH变量中但仍然得到相同的错误,即使我们检查过PATH确实包含查找模块的路径。

我们在Linux Ubuntu 13.10上使用Python 2.7。

我们有什么可能做错的吗?

提前致谢,

4 个答案:

答案 0 :(得分:6)

在运行包含在包中的脚本时正确获取导入是很棘手的。您可以阅读this section of the (sadly deferred) PEP 395,了解一些无法运行此类脚本的方法的说明。

提供文件系统层次结构,如:

top_level/
    my_package/
        __init__.py
        sub_package/
            __init__.py
            module_a.py
            module_b.py
            sub_sub_package/
                __init__.py
                module_c.py
        scripts/
            __init__.py
            my_script.py
            script_subpackage/
                 __init__.py
                 script_module.py

只有几种方法可以使my_script.py正常运行。

  1. 第一个是将top_level文件夹放入PYTHONPATH环境变量,或使用.pth文件来实现同样的目的。或者,一旦解释器运行,将该文件夹插入sys.path(但这可能会变得丑陋)。

    请注意,您要在路径中添加top_level,而不是my_package!我怀疑这是你在目前尝试这个解决方案时搞砸了。它很容易出错。

    然后,像import my_package.sub_package.module_a这样的绝对导入将大部分正常工作。 (当它作为package.scripts.my_script模块运行时,不要尝试导入__main__,否则你将得到一个奇怪的模块副本。)

    但是,绝对导入总是比相对导入更冗长,因为即使您从{导入兄弟模块(或“侄女”模块,如module_c),您总是需要指定完整路径。 {1}})。对于绝对导入,获取module_a的方式始终是代码module_c的大而丑陋,无论导入哪个模块。

  2. 因此,使用相对导入通常更优雅。唉,他们很难从剧本中开始工作。唯一的方法是:

    1. 使用from my_package.sub_package.sub_sub_package import module_c标记(例如my_script)从top_level文件夹运行-m,永远不要使用文件名。

      如果您位于其他文件夹中,或者使用其他方法运行脚本(例如在IDE中按F5),则无效。这有点不灵活,但实际上并没有任何方法可以让它变得更容易(直到PEP 395被推迟和实施)。

    2. 为绝对导入设置python -m my_package.scripts.my_script(例如将sys.path添加到top_level或其他内容),然后使用PEP 366 PYTHONPATH字符串告诉Python你的脚本的预期包是什么。也就是说,在__package__中,您希望将所有类似的内容放在所有相对导入之上:

      my_script.py

      如果您重新组织文件组织并将脚本移动到另一个包中,则需要更新(但这可能比更新大量绝对导入的工作少)。

    3. 一旦你实施了其中一个产品,你的进口就会变得更简单。从if __name__ == "__main__" and __package__ is None: __package__ = "my_package.my_scripts" 导入module_c变为module_a。在from .sub_sub_package import module_c中,my_script之类的相对导入将起作用。

答案 1 :(得分:1)

刚刚开始     __pacage__ = None每个 .py文件中。它将自动设置所有包层次结构。

之后,您可以自由使用绝对模块名称进行导入。

from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector

答案 2 :(得分:0)

导入工作的方式在Python 2和3中略有不同。第一个Python 3和理智的方式(你似乎期望)。在Python 3中,所有导入都与sys.pathsee here中的文件夹相关,有关模块搜索路径的更多信息)。顺便说一下,Python不使用$PATH

因此,您可以从任何地方导入任何内容,而无需担心太多。

在Python 2中,导入是相对的,有时是绝对的。 document about packages包含一个示例布局和一些可能对您有用的导入语句。

Intra-package References”部分包含有关如何在包之间导入的信息。

综上所述,我认为你的sys.path是错误的。确保包含 algorithms的文件夹(即 algorithms本身,但它的父级)需要位于sys.path

答案 3 :(得分:0)

我知道这是一个老帖子,但我仍然会发布我的解决方案。

有类似的问题。在导入包之前,只需使用以下行添加路径:

sys.path.append(os.path.join(os.path.dirname(__file__), '..')) 
from lib import create_graph