虚拟环境在不该使用系统包时使用了系统包

3 投票
2 回答
2869 浏览
提问于 2025-04-16 03:53

我创建了一个虚拟环境,使用了 --no-site-packages 这个选项。激活虚拟环境后,我发现如果在 "python" 提示符下导入 psycopg2,会导入我系统中过时的库;而在 "python2.6" 提示符下导入时,则会导入我在虚拟环境中安装的更新版本的库。

这是为什么呢?在激活虚拟环境时,怎样才能只使用虚拟环境中的包呢?

我在使用 OS X 系统,如果这有影响的话。

根据 Jeff 的评论,我补充一下:

在我的虚拟环境的 /bin 目录下,有 "python" 和 "python2.6" 两个可执行文件。"python2.6" 是指向 "python" 的一个符号链接,而 "python" 是一个二进制文件。

(ice_development)[jacob@Beagle:~] $ ls -l Virtualenv/ice_development/bin/
total 264
-rw-r--r--  1 jacob  staff   2086 Sep  8 18:13 activate

 .....

-rwxr-xr-x  1 jacob  staff  50720 Sep  8 18:13 python
lrwxr-xr-x  1 jacob  staff      6 Sep  8 18:13 python2.6 -> python

在激活虚拟环境后,执行 "which python" 和 "which python2.6" 都指向虚拟环境的目录。

(ice_development)[jacob@Beagle:~] $ which python
/Users/jacob/Virtualenv/ice_development/bin/python
(ice_development)[jacob@Beagle:~] $ which python2.6
/Users/jacob/Virtualenv/ice_development/bin/python2.6
(ice_development)[jacob@Beagle:~] $ 

而且,在命令行使用这些可执行文件后,提示符是一样的。

(ice_development)[jacob@Beagle:~] $ python2.6
Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import psycopg2
>>> psycopg2.__version__
'2.2.2 (dt dec ext pq3)'
>>> quit()

(ice_development)[jacob@Beagle:~] $ python
Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import psycopg2
>>> psycopg2.__version__
'2.0.13 (dt dec ext pq3)'
>>> quit()

~/ENV/lib/python2.6/site-packages 目录里包含了 psycopg2 的新版本(2.2.2):

(ice_development)[jacob@Beagle:~] $ ls Virtualenv/ice_development/lib/python2.6/site-   packages/
Twisted-10.1.0-py2.6-macosx-10.6-universal.egg       setuptools-0.6c11-py2.6.egg
easy-install.pth                                     setuptools.pth
pip-0.7.2-py2.6.egg                                  txpostgres-0.3.0-py2.6.egg
psycopg2                                             zope.interface-3.6.1-py2.6-macosx-    10.6-universal.egg
psycopg2-2.2.2-py2.6.egg-info

然而,在不同的提示符下导入 psycopg2 却会导入两个不同的版本。

2 个回答

1

感谢xnine的回复,我想到了要检查我的.bashrc文件。我把这些行注释掉了:

export PATH=/usr/bin/python2.6:$PATH
alias python="/usr/bin/python2.6"
alias pdb='python -m pdb'

其中一行解决了我的问题。

1

我一直在尝试复现你遇到的问题,但没有成功。

激活虚拟环境后,我的命令行提示符变成了这样:

jeff@DeepThought:~$ source ~/ENV/bin/activate
(ENV)jeff@DeepThought:~$ 

这主要是把 ~/ENV/bin 加到搜索路径的最前面,所以当我输入“python”时,系统会优先找到这个路径下的 Python 版本。在我的情况下,我全局安装了 2.6 版本,而在虚拟环境中安装了 2.7 版本。

(ENV)jeff@DeepThought:~$ python
Python 2.7 (r27:82500, Sep  8 2010, 20:09:26) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

我觉得你情况中奇怪的是,你说你的更新库在虚拟环境里,但你只能用 python2.6 来访问它们。除非你自己创建了这个环境,~/ENV/bin 里应该根本没有 python2.6 的可执行文件。如果你激活了虚拟环境,输入 python 应该会进入虚拟环境的 Python 终端,而输入 python2.6 则会进入全局的 Python 终端。如果真是这样,你看到的情况应该和你描述的正好相反。

我首先会检查一下当你运行 python 和 python2.6 时,实际执行了什么:

(ENV)jeff@DeepThought:~$ which python
/home/jeff/ENV/bin/python
(ENV)jeff@DeepThought:~$ which python2.6
/usr/bin/python2.6

这看起来和我预期的一样。你的情况是什么样的?如果你的情况也这样,可能你需要进入 ~/ENV/lib/python2.6/site-packages/ 目录,删除那些出问题的文件,然后用更新后的文件替换它们。

补充:别名的优先级高于搜索路径:

jeff@DeepThought:~$ echo $PATH
/home/jeff/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
jeff@DeepThought:~$ cat > /home/jeff/bin/hello.sh
#!/bin/bash
echo "hello world"
jeff@DeepThought:~$ chmod +x ~/bin/hello.sh 
jeff@DeepThought:~$ hello.sh
hello world
jeff@DeepThought:~$ which hello.sh
/home/jeff/bin/hello.sh
jeff@DeepThought:~$ alias hello.sh=/usr/bin/python
jeff@DeepThought:~$ which hello.sh
/home/jeff/bin/hello.sh
jeff@DeepThought:~$ hello.sh
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

撰写回答