Python 加载模块时使用 sys.path.insert(0, path) 和 sys.path(append) 的效果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31291608/
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
Effect of using sys.path.insert(0, path) and sys.path(append) when loading modules
提问by Michael Barton
I was recently having a problem with a python ImportError, where the module was found when running on my local computer but not found on the CI server. I solved this problem by swapping sys.path.append(path)
in my script with sys.path.insert(0, path)
where path
is the string module location.
我最近遇到了 python ImportError 的问题,在我的本地计算机上运行时找到了该模块,但在 CI 服务器上找不到。我通过sys.path.append(path)
在我的脚本中交换字符串模块位置sys.path.insert(0, path)
在哪里解决了这个问题path
。
Since this is my module and not an installed package (related question), why does the order of paths fix this problem?
由于这是我的模块而不是已安装的包(相关问题),为什么路径顺序可以解决此问题?
采纳答案by Anand S Kumar
Because python checks in the directories in sequential order starting at the first directory in sys.path
list, till it find the .py
file it was looking for.
因为python从sys.path
列表中的第一个目录开始按顺序检查目录,直到找到它要查找的.py
文件。
Ideally, the current directory or the directory of the script is the first always the first element in the list, unless you modify it, like you did. From documentation-
理想情况下,当前目录或脚本目录始终是列表中的第一个元素,除非您像以前那样修改它。从文档-
As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of PYTHONPATH.
在程序启动时初始化,此列表的第一项 path[0] 是包含用于调用 Python 解释器的脚本的目录。如果脚本目录不可用(例如,如果以交互方式调用解释器或从标准输入读取脚本),则 path[0] 是空字符串,它指示 Python 首先搜索当前目录中的模块。请注意,脚本目录插入在作为 PYTHONPATH 的结果插入的条目之前。
So, most probably, you had a .py
file with the same name as the module you were trying to import from, in the current directory (where the script was being run from).
因此,很可能,您.py
在当前目录(运行脚本的位置)中有一个与您尝试从中导入的模块同名的文件。
Also, a thing to note about ImportError
s , lets say the import error says -
ImportError: No module named main
- it doesn't mean the main.py
is overwritten, no if that was overwritten we would not be having issues trying to read it. Its some module above this that got overwritten with a .py
or some other file.
另外,关于ImportError
s需要注意的一点是,假设导入错误说 -
ImportError: No module named main
- 这并不意味着它main.py
被覆盖,不,如果它被覆盖,我们就不会在尝试读取它时遇到问题。它上面的某个模块被 . py
或其他一些文件。
Example -
例子 -
My directory structure looks like -
我的目录结构看起来像 -
- test
- shared
- __init__.py
- phtest.py
- testmain.py
Now From testmain.py
, I call from shared import phtest
, it works fine.
现在从testmain.py
,我打电话给from shared import phtest
,它工作正常。
Now lets say I introduce a shared.py in test
directory` , example -
现在假设我在test
directory` 中引入了一个 shared.py ,例如 -
- test
- shared
- __init__.py
- phtest.py
- testmain.py
- shared.py
Now when I try to do from shared import phtest
from testmain.py
, I will get the error -
现在,当我尝试执行from shared import phtest
from 时testmain.py
,我会收到错误消息 -
ImportError: cannot import name 'phtest'
As you can see above, the file that is causing the issue is shared.py
, not phtest.py
.
正如您在上面看到的,导致问题的文件是shared.py
,而不是phtest.py
.
回答by herve-guerin
I'm quite a beginner in Python and I found the answer of Anand was very good but quite complicated to me, so I try to reformulate :
我是 Python 的初学者,我发现 Anand 的答案非常好,但对我来说很复杂,所以我尝试重新表述:
1) insert
and append
methods are not specific to sys.path
and as in other languages they add an item into a list or array and :
* append(item)
add item
to the end of the list,
* insert(n, item)
inserts the item
at the nth position in the list (0
at the beginning, 1
after the first element, etc ...).
1)insert
和append
方法不特定于sys.path
和其他语言它们添加项目到一个列表或阵列和:
*append(item)
添加item
到列表的末尾,
*insert(n, item)
嵌入式item
在该列表中的第n个位置(0
在开始,1
后第一个元素,等等......)。
2) As Anand said, python search the import files in each directory of the path in the order of the path, so :
* If you have no file name collisions, the order of the path has no impact,
* If you look after a function already defined in the path and you use append
to add your path, you will not get your function but the predefined one.
2)正如Anand所说,python按照路径的顺序搜索路径的每个目录下的导入文件,所以:
*如果没有文件名冲突,路径的顺序没有影响,
*如果你照顾一个函数已经在路径中定义并且你append
用来添加你的路径,你不会得到你的函数,而是预定义的函数。
But I think that it is better to use append
and not insert
to not overload the standard behaviour of Python, and use non-ambiguous names for your files and methods.
但我认为最好使用append
而不是insert
重载 Python 的标准行为,并为您的文件和方法使用明确的名称。