Wil*_*uks 8 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
Run Code Online (Sandbox Code Playgroud)
我们一直在努力将模块从一个文件夹导入到另一个文件夹,例如:
from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector
Run Code Online (Sandbox Code Playgroud)
结果如下:
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
Run Code Online (Sandbox Code Playgroud)
我们尝试将其路径附加到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
Run Code Online (Sandbox Code Playgroud)
只有几种方法可以使正常运行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从module_a).对于绝对导入,无论使用哪个模块进行导入,获取module_c方式始终是大而丑陋的代码from my_package.sub_package.sub_sub_package import module_c.
因此,使用相对导入通常更优雅.唉,他们很难从剧本中开始工作.唯一的方法是:
运行my_script从top_level与文件夹-m标志(如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"
Run Code Online (Sandbox Code Playgroud)
如果您重新组织文件组织并将脚本移动到另一个包,则需要更新(但这可能比更新大量绝对导入的工作少).
一旦你实现了其中一个,你的导入就会变得更简单.module_c从中导入module_a变为from .sub_sub_package import module_c.在my_script,像这样的相对进口from ..subpackage import module_a只会起作用.
Python 2 和 3 中导入的工作方式略有不同。首先是 Python 3 和正常的方式(您似乎期望的)。在Python 3中,所有导入都是相对于sys.path(有关模块搜索路径的更多信息,请参阅此处)中的文件夹的。$PATH顺便说一句,Python 不使用。
因此,您可以从任何地方导入任何东西,而不必担心太多。
在 Python 2 中,导入是相对的,有时是绝对的。有关包的文档包含示例布局和一些可能对您有用的导入语句。
“包内引用”部分包含有关如何在包之间导入的信息。
综上所述,我认为你的观点sys.path是错误的。确保包含 algorithms的文件夹(即不是它 algorithms本身,而是它的父级)需要位于sys.path