给出以下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。
我们有什么可能做错的吗?
提前致谢,
答案 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
正常运行。
第一个是将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
的大而丑陋,无论导入哪个模块。
因此,使用相对导入通常更优雅。唉,他们很难从剧本中开始工作。唯一的方法是:
使用from my_package.sub_package.sub_sub_package import module_c
标记(例如my_script
)从top_level
文件夹运行-m
,永远不要使用文件名。
如果您位于其他文件夹中,或者使用其他方法运行脚本(例如在IDE中按F5),则无效。这有点不灵活,但实际上并没有任何方法可以让它变得更容易(直到PEP 395被推迟和实施)。
为绝对导入设置python -m my_package.scripts.my_script
(例如将sys.path
添加到top_level
或其他内容),然后使用PEP 366 PYTHONPATH
字符串告诉Python你的脚本的预期包是什么。也就是说,在__package__
中,您希望将所有类似的内容放在所有相对导入之上:
my_script.py
如果您重新组织文件组织并将脚本移动到另一个包中,则需要更新(但这可能比更新大量绝对导入的工作少)。
一旦你实施了其中一个产品,你的进口就会变得更简单。从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.path
(see 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