为什么使用 sys.path.append (path)而不是 sys.path.insert (1,path) ?

编辑: 基于 Ulf Rompe 的评论,用“1”代替“0”很重要,否则你将破坏 Sys.path

我做 python 已经有一段时间了(超过一年) ,我一直很困惑为什么人们推荐你使用 sys.path.append()而不是 sys.path.insert()。我来示范一下。

假设我正在处理一个名为 PyWorkbooks (安装在我的计算机上)的模块,但是我同时在处理一个包含 PyWorkbooks 的不同模块(假设是 PyJob)。在使用 PyJob 时,我发现 PyWorkbooks 中有一些错误,我正在纠正它们,因此我想导入一个开发版本。

有多种方法可以同时处理这两个问题(例如,我可以将我的 PyWorkbooks 项目放在 PyJob 内部) ,但是有时我仍然需要使用这个路径。然而,我不能简单地对 PyWorkbooks 所在的文件夹执行 sys.path.append()操作。为什么?因为 python 会首先找到我安装的 PyWorkbooks!

这就是为什么必须执行 sys.path.insert (1,path _ to _ dev _ pyworkbooks)

总之:

sys.path.append(path_to_dev_pyworkbooks)
import PyWorkbooks # does NOT import dev pyworkbooks, imports installed one

或:

sys.path.insert(1, path_to_dev_pyworkbooks) # based on comments you should use **1 not 0**
import PyWorkbooks # imports correct file

这在过去给我带来了一些麻烦,如果我们(作为一个社区)开始推荐 sys.path.insert(1, path),就像你手动插入一个路径一样,我认为可以安全地说,这就是你想要使用的路径!

还是我做错了什么?这个问题有时候会困扰我,我希望它公开!

135529 次浏览

If you have multiple versions of a package / module, you need to be using virtualenv (emphasis mine):

virtualenv is a tool to create isolated Python environments.

The basic problem being addressed is one of dependencies and versions, and indirectly permissions. Imagine you have an application that needs version 1 of LibFoo, but another application requires version 2. How can you use both these applications? If you install everything into /usr/lib/python2.7/site-packages (or whatever your platform’s standard location is), it’s easy to end up in a situation where you unintentionally upgrade an application that shouldn’t be upgraded.

Or more generally, what if you want to install an application and leave it be? If an application works, any change in its libraries or the versions of those libraries can break the application.

Also, what if you can’t install packages into the global site-packages directory? For instance, on a shared host.

In all these cases, virtualenv can help you. It creates an environment that has its own installation directories, that doesn’t share libraries with other virtualenv environments (and optionally doesn’t access the globally installed libraries either).

That's why people consider insert(0, to be wrong -- it's an incomplete, stopgap solution to the problem of managing multiple environments.

If you really need to use sys.path.insert, consider leaving sys.path[0] as it is:

sys.path.insert(1, path_to_dev_pyworkbooks)

This could be important since 3rd party code may rely on sys.path documentation conformance:

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.

you are confusing the concept of appending and prepending. the following code is prepending:

sys.path.insert(1,'/thePathToYourFolder/')

it places the new information at the beginning (well, second, to be precise) of the search sequence that your interpreter will go through. sys.path.append() puts things at the very end of the search sequence.

it is advisable that you use something like virtualenv instead of manually coding your package directories into the PYTHONPATH everytime. for setting up various ecosystems that separate your site-packages and possible versions of python, read these two blogs:

  1. python ecosystems introduction

  2. bootstrapping python virtual environments

if you do decide to move down the path to environment isolation you would certainly benefit by looking into virtualenvwrapper: http://www.doughellmann.com/docs/virtualenvwrapper/