Python没有找到模块
鉴于以下PyDev中创建的python项目:
├── 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。
有什么我们可能做错了吗?
提前致谢,
运行包含在包内的脚本时正确导入是非常棘手的。 您可以阅读(可悲推迟的)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
正常运行。
第一种方法是将top_level
文件夹放入PYTHONPATH
环境变量中,或者使用.pth
文件实现相同的功能。 或者,一旦解释器正在运行,将该文件夹插入到sys.path
(但这会变得很难看)。
请注意,您正在向路径添加top_level
,而不是my_package
! 我怀疑这是你在这个解决方案的当前尝试中搞砸了。 它很容易出错。
然后,像import my_package.sub_package.module_a
这样的绝对import my_package.sub_package.module_a
将大部分工作正常。 (只是不要在它作为__main__
模块运行时尝试导入package.scripts.my_script
本身,否则会得到一个奇怪的模块副本。)
但是,绝对导入将始终比相对导入更加冗长,因为即使导入兄弟模块(或“ module_a
”模块,如module_a
module_c
),您也始终需要指定完整路径。 对于绝对导入,获取module_c
方式始终是from my_package.sub_package.sub_sub_package import module_c
大而难看的from my_package.sub_package.sub_sub_package import module_c
代码from my_package.sub_package.sub_sub_package import module_c
哪个模块。
出于这个原因,使用相对导入通常更优雅。 唉,他们很难从脚本开始工作。 唯一的方法是:
使用-m
标志从top_level
文件夹运行my_script
(例如python -m my_package.scripts.my_script
),而不要使用文件名。
如果您位于不同的文件夹中,或者您使用其他方法来运行脚本(如在IDE中按F5),它将不起作用。 这有点不灵活,但没有任何方法可以使它更容易(直到PEP 395被取消并执行)。
像绝对导入一样设置sys.path
(例如,将top_level
添加到PYTHONPATH
或其他东西),然后使用PEP 366 __package__
字符串告诉Python脚本的期望包是什么。 也就是说,在my_script.py
您希望在所有相关导入之上放置这样的东西:
if __name__ == "__main__" and __package__ is None:
__package__ = "my_package.my_scripts"
如果重新组织文件组织并将脚本移动到不同的包中,这将需要更新(但这可能比更新大量绝对导入要少)。
一旦你实现了其中一个soutions,你的进口可以变得更简单。 导入module_c
从module_a
成为from .sub_sub_package import module_c
。 在my_script
, from ..subpackage import module_a
相对from ..subpackage import module_a
将会正常工作。
在Python 2和Python 3中,导入工作的方式略有不同。第一个Python 3和一种理智的方式(您似乎期待)。 在Python 3中,所有导入都是相对于sys.path
的文件夹(请参阅此处了解有关模块搜索路径的更多信息)。 顺便说一句,Python不使用$PATH
。
所以你可以从任何地方导入任何东西,而不用担心太多。
在Python 2中,导入是相对的,有时是绝对的。 有关包的文档包含一个示例布局和一些可能对您有用的导入语句。
“内部包引用”部分包含有关如何在包之间导入的信息。
从以上所有,我认为你的sys.path
是错误的。 确保包含algorithms
的文件夹(即不是algorithms
本身,但它是父项)需要在sys.path
只需在每个 .py文件中设置__pacage__ = None
。 它会自动设置所有包层次结构。
之后,您可以自由使用绝对模块名称进行导入。
from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector