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

Why use sys.path.append(path) instead of 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)的原因

综上所述:

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

要么:

1
2
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),我真的很喜欢它,就像你手动插入路径一样我认为可以安全地说这是你想要使用的路径!

或者我有什么不对劲?这个问题有时会困扰我,我希望它在公开场合!


如果您有多个版本的软件包/模块,则需要使用virtualenv(强调我的):

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).

这就是为什么人们认为insert(0,是错误的 - 这是管理多个环境问题的一个不完整的,权宜之计的解决方案。


如果您确实需要使用sys.path.insert,请考虑保留sys.path [0]:

1
sys.path.insert(1, path_to_dev_pyworkbooks)

这可能很重要,因为第三方代码可能依赖于sys.path文档一致性:

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.


你混淆了追加和前置的概念。以下代码是前置代码:

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

它将新信息放在解释器将要经历的搜索序列的开头(嗯,第二,确切地说)。 sys.path.append()将事物置于搜索序列的最后。

建议您使用类似virtualenv的内容,而不是每次都将包目录手动编码到PYTHONPATH中。要设置各种生态系统来分离您的站点包和可能的python版本,请阅读以下两个博客:

  • python生态系统介绍

  • bootstrapping python虚拟环境

  • 如果你决定走向环境隔离的道路,你肯定会受益于virtualenvwrapper:http://www.doughellmann.com/docs/virtualenvwrapper/