Python未找到模块
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19972669/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Not Finding Module
提问by Willian Fuks
Given the following python project, created in PyDev:
给定以下在 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
We've been trying with no success to import modules from one folder to another, such as:
我们一直在尝试将模块从一个文件夹导入到另一个文件夹,但没有成功,例如:
from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector
Which yields the result:
结果如下:
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
We tried to append its path to the sys.path variable but with no success.
我们尝试将其路径附加到 sys.path 变量,但没有成功。
We also tried to use os.walk to insert all paths into PATH variable but still we get the same error, even though we checked PATH does contain the path to find the modules.
我们还尝试使用 os.walk 将所有路径插入到 PATH 变量中,但仍然出现相同的错误,即使我们检查 PATH 确实包含查找模块的路径。
We are using Python 2.7 on Linux Ubuntu 13.10.
我们在 Linux Ubuntu 13.10 上使用 Python 2.7。
Is there anything we could be doing wrong?
有什么我们可能做错的吗?
Thanks in advance,
提前致谢,
回答by Aaron Digulla
The way imports work is slightly different in Python 2 and 3. First Python 3 and the sane way (which you seem to expect). In Python 3, all imports are relative to the folders in sys.path
(see herefor more about the module search path). Python doesn't use $PATH
, by the way.
导入工作的方式在 Python 2 和 3 中略有不同。首先是 Python 3 和理智的方式(您似乎期望)。在 Python 3 中,所有导入都相对于中的文件夹sys.path
(有关模块搜索路径的更多信息,请参见此处)。$PATH
顺便说一下,Python 不使用。
So you can import anything from anywhere without worrying too much.
所以你可以从任何地方导入任何东西而不必担心。
In Python 2, imports are relative and sometimes absolute. The document about packagescontains an example layout and some import statements which might be useful for you.
在 Python 2 中,导入是相对的,有时是绝对的。关于包的文档包含一个示例布局和一些可能对您有用的导入语句。
The section "Intra-package References" contains information about how to import between packages.
“包内引用”部分包含有关如何在包之间导入的信息。
From all the above, I think that your sys.path
is wrong. Make sure the folder which containsalgorithms
(i.e. notalgorithms
itself but it's parent) needs to be in sys.path
综上所述,我认为你sys.path
是错的。确保包含的文件夹algorithms
(即不是algorithms
它本身,而是它的父文件夹)需要在sys.path
回答by Blckknght
Getting imports right when running a script that lives within a package is tricky. You can read this section of the (sadly deferred) PEP 395for a description of a bunch of ways that don't work to run such a script.
在运行包中的脚本时正确导入是很棘手的。您可以阅读(遗憾地推迟)PEP 395 的这一部分,以了解无法运行此类脚本的一系列方法。
Give a file system hierarchy like:
给出一个文件系统层次结构,如:
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
There are only a few ways to make running my_script.py
work right.
只有几种方法可以使跑步my_script.py
正常工作。
The first would be to put the
top_level
folder into thePYTHONPATH
environment variable, or use a.pth
file to achieve the same thing. Or, once the interpreter is running, insert that folder intosys.path
(but this can get ugly).Note that you're adding
top_level
to the path, notmy_package
! I suspect this is what you've got messed up in your current attempts at this solution. Its very easy to get wrong.Then, absolute imports like
import my_package.sub_package.module_a
will mostly work correctly. (Just don't try importingpackage.scripts.my_script
itself while it is running as the__main__
module, or you'll get a weird duplicate copy of the module.)However, absolute imports will always be more verbose than relative imports, since you always need to specify the full path, even if you're importing a sibling module (or "niece" module, like
module_c
frommodule_a
). With absolute imports, the way to getmodule_c
is always the big, ugly mouthful of codefrom my_package.sub_package.sub_sub_package import module_c
regardless of what module is doing the importing.For that reason, using relative imports is often more elegant. Alas, they're hard to get to work from a script. The only ways are:
Run
my_script
from thetop_level
folder with the-m
flag (e.g.python -m my_package.scripts.my_script
) and never by filename.It won't work if you're in a different folder, or if you use a different method to run the script (like pressing F5 in an IDE). This is somewhat inflexible, but there's not really any way to make it easier (until PEP 395 gets undeferred and implemented).
Set up
sys.path
like for absolute imports (e.g. addtop_level
toPYTHONPATH
or something), then use a PEP 366__package__
string to tell Python what the expected package of your script is. That is, inmy_script.py
you'd want to put something like this above all your relative imports:if __name__ == "__main__" and __package__ is None: __package__ = "my_package.my_scripts"
This will require updating if you reorganize your file organization and move the script to a different package (but that's probably less work than updating lots of absolute imports).
Once you've implemented one of those soutions, your imports can get simpler. Importing
module_c
frommodule_a
becomesfrom .sub_sub_package import module_c
. Inmy_script
, relative imports likefrom ..subpackage import module_a
will just work.
第一种方法是将
top_level
文件夹放入PYTHONPATH
环境变量中,或者使用.pth
文件来实现相同的目的。或者,一旦解释器运行,将该文件夹插入sys.path
(但这可能会变得丑陋)。请注意,您要添加
top_level
到路径中,而不是my_package
! 我怀疑这就是您当前尝试使用此解决方案时遇到的问题。它很容易出错。然后,绝对导入之类的
import my_package.sub_package.module_a
大多数情况下都可以正常工作。(只是不要package.scripts.my_script
在它作为__main__
模块运行时尝试导入它自己,否则你会得到一个奇怪的模块副本。)但是,绝对导入总是比相对导入更冗长,因为您总是需要指定完整路径,即使您正在导入同级模块(或“侄女”模块,如
module_c
frommodule_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
like 绝对导入(例如添加top_level
到PYTHONPATH
或其他内容),然后使用PEP 366__package__
字符串告诉 Python 脚本的预期包是什么。也就是说,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
,相对导入就像from ..subpackage import module_a
会起作用。
回答by voddan
Just set
__pacage__ = None
in every.py file. It will setup all the package hierarchy automatically.
只需__pacage__ = None
在每个.py 文件中设置即可
。它将自动设置所有包层次结构。
After that you may freely use absolute module names for import.
之后,您可以自由使用绝对模块名称进行导入。
from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector
from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector
回答by G. Deg
I know this is an old post but still I am going to post my solution.
我知道这是一个旧帖子,但我仍然要发布我的解决方案。
Had a similar issue. Just added the paths with the following line before importing the package:
有一个类似的问题。在导入包之前,只需添加以下行的路径:
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from lib import create_graph