给定以下在 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
大部分都会正常工作。 (只是不要尝试导入package.scripts.my_script
当它作为__main__
模块,否则你会得到该模块的奇怪的重复副本。)
但是,绝对导入总是比相对导入更详细,因为您始终需要指定完整路径,即使您正在导入同级模块(或“侄女”模块,例如module_c
from module_a
)。绝对进口,获得方式module_c
总是一大堆丑陋的代码from my_package.sub_package.sub_sub_package import module_c
无论哪个模块正在执行导入。
-
因此,使用相对导入通常更优雅。唉,他们很难按照剧本开始工作。唯一的方法是:
-
Run my_script
来自top_level
文件夹与-m
标志(例如python -m my_package.scripts.my_script
)而不是按文件名。
如果您位于不同的文件夹中,或者使用不同的方法来运行脚本(例如在 IDE 中按 F5),它将不起作用。这有点不灵活,但实际上没有任何方法可以使它变得更容易(直到 PEP 395 得到取消和实施)。
-
Set up sys.path
就像绝对导入一样(例如添加top_level
to PYTHONPATH
或其他东西),然后使用PEP 366 __package__
字符串告诉 Python 脚本的预期包是什么。也就是说,在my_script.py
你想把这样的东西放在所有相对导入之上:
if __name__ == "__main__" and __package__ is None:
__package__ = "my_package.my_scripts"
如果您重新组织文件组织并将脚本移动到不同的包,这将需要更新(但这可能比更新大量绝对导入的工作量要少)。
一旦您实施了其中一种解决方案,您的导入就会变得更加简单。输入module_c
from module_a
变成from .sub_sub_package import module_c
. In my_script
,相对进口如from ..subpackage import module_a
就会起作用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)