在开发Python应用程序时,系统默认的Python版本可能会不兼容这个应用程序, 如果同时开发多个应用程序, 可能会用到好几个版本的python环境, 这种情况下,每个应用可能需要各自拥有一套"独立"的Python运行环境。 Virtual env就是用来为一个应用创建一套"隔离"的Python运行环境的工具。 Virtual env是python的一个虚拟化环境工具,用来建立一个虚拟的python环境,一个专属于项目的python环境, 用 Virtual env 来保持一个干净的环境非常有用, 可以帮助我们在同一台host上创建多套纯净的python解释器环境并实现相互隔离,各个环境下安装的库仅限于自己的环境,不会影响到别人。
动态语言Ruby、Python都有自己的虚拟环境,虚拟环境是程序执行时的独立执行环境,在同一台服务器中可以创建不同的虚拟环境供不同的系统使用,项目之间的运行环境保持独立性而相互不受影响。例如项目A在基于Python2的环境中运行,而项目B可以在基于Python3的环境中运行。Python通 Virtual env工具管理虚拟环境。
简而言之, Virtual env是一个创建隔绝的Python环境的工具。 Virtual env创建一个包含所有必要的可执行文件的文件夹,用来使用Python工程所需的包。 Virtual env用于创建独立的Python环境,多个Python相互独立,互不影响,它能够帮助: - 在没有权限的情况下安装新套件; - 不同应用可以使用不同的套件版本; - 套件升级不影响其他应用。 - 隔离项目之间的第三方包依赖 - 在没有权限的情况下安装新的Python软件包 - 还有一个额外的好处:部署应用时,把开发环境的虚拟环境打包到生产环境即可。
Virtual env 安装
[root@kevin-test ~]# cat /etc/redhat-release (本文是在centos7下操作并验证无误) CentOS Linux release 7.5.1804 (Core) [root@kevin-test ~]# python -V Python 2.7.5 [root@kevin-test ~]# pip -V -bash: pip: command not found 先来安装pip [root@kevin-test ~]# yum -y install epel-release [root@kevin-test ~]# yum install python-pip [root@kevin-test ~]# pip install --upgrade pip [root@kevin-test ~]# pip -V pip 18.1 from /usr/lib/python2.7/site-packages/pip (python 2.7) 通过pip安装 Virtual env [root@kevin-test ~]# pip install Virtual env Collecting Virtual env Downloading https://files.pythonhosted.org/packages/7c/17/9b7b6cddfd255388b58c61e25b091047f6814183e1d63741c8df8dcd65a2/ Virtual env-16.1.0-py2.py3-none-any.whl (1.9MB) 100% |████████████████████████████████| 1.9MB 1.3MB/s Installing collected packages: Virtual env Successfully installed Virtual env-16.1.0 测试安装后 Virtual env的版本 [root@kevin-test ~]# Virtual env --version 16.1.0 查看帮助 [root@kevin-test ~]# Virtual env --help Usage: Virtual env [OPTIONS] DEST_DIR Options: --version show program's version number and exit -h, --help show this help message and exit -v, --verbose Increase verbosity. -q, --quiet Decrease verbosity. -p PYTHON_EXE, --python=PYTHON_EXE The Python interpreter to use, e.g., --python=python3.5 will use the python3.5 interpreter to create the new environment. The default is the interpreter that Virtual env was installed with (/usr/bin/python2) --clear Clear out the non-root install and start from scratch. --no-site-packages DEPRECATED. Retained only for backward compatibility. Not having access to global site-packages is now the default behavior. --system-site-packages Give the Virtual environment access to the global site-packages. --always-copy Always copy files rather than symlinking. --relocatable Make an EXISTING Virtual env environment relocatable. This fixes up scripts and makes all .pth files relative. --no-setuptools Do not install setuptools in the new Virtual env. --no-pip Do not install pip in the new Virtual env. --no-wheel Do not install wheel in the new Virtual env. --extra-search-dir=DIR Directory to look for setuptools/pip distributions in. This option can be used multiple times. --download Download preinstalled packages from PyPI. --no-download, --never-download Do not download preinstalled packages from PyPI. --prompt=PROMPT Provides an alternative prompt prefix for this environment. --setuptools DEPRECATED. Retained only for backward compatibility. This option has no effect. --distribute DEPRECATED. Retained only for backward compatibility. This option has no effect. --unzip-setuptools DEPRECATED. Retained only for backward compatibility. This option has no effect.
Virtual env 使用
现在为某一个工程创建一个虚拟环境, 创建一个独立的Python运行环境,命名为pj_test (这是虚拟环境目录名,目录名可自行自定义) [root@kevin-test ~]# cd /opt/ [root@kevin-test opt]# mkdir project_test [root@kevin-test opt]# cd project_test [root@kevin-test project_test]# Virtual env --no-site-packages pj_test New python executable in /opt/project_test/pj_test/bin/python2 Also creating executable in /opt/project_test/pj_test/bin/python Installing setuptools, pip, wheel... done. 如上命令 Virtual env就可以创建一个独立的Python运行环境,这里还加上了参数--no-site-packages (也可以不跟这个参数),这样已经安装到系统Python环境 中的所有第三方包都不会复制过来,于是就得到了一个不带任何第三方包的"干净"的Python运行环境。 上面命令将会在当前的目录中创建一个文件夹pj_test,这个文件夹包含一些Python执行文件,以及pip副本,用于安装其他的packges。 虚拟环境的名字(此例中是pj_test )可以是任意的;若省略名字将会把文件均放在当前目录。 [root@kevin-test project_test]# ls pj_test [root@kevin-test project_test]# ls pj_test/ bin include lib lib64 [root@kevin-test project_test]# yum install -y tree [root@kevin-test project_test]# tree pj_test/bin pj_test/bin ├── activate ├── activate.csh ├── activate.fish ├── activate.ps1 ├── activate_this.py ├── easy_install ├── easy_install-2.7 ├── pip ├── pip2 ├── pip2.7 ├── python -> python2 ├── python2 ├── python2.7 -> python2 ├── python-config └── wheel [root@kevin-test project_test]# tree pj_test/include/ pj_test/include/ └── python2.7 -> /usr/include/python2.7 [root@kevin-test project_test]# tree pj_test/lib| head -3 pj_test/lib └── python2.7 ├── _abcoll.py -> /usr/lib64/python2.7/_abcoll.py 新建的Python环境被放到当前目录下的pj_test目录。有了pj_test这个Python环境,可以用source激活虚拟环境: [root@kevin-test project_test]# pwd /opt/project_test [root@kevin-test project_test]# ls pj_test [root@kevin-test project_test]# cd pj_test/ [root@kevin-test pj_test]# source ./bin/activate (pj_test) [root@kevin-test pj_test]# python -V Python 2.7.5 激活虚拟环境, 在虚拟环境里, 任何使用pip安装的包将会放在 venv 文件夹中,与全局安装或其他应用的Python环境完全隔绝开。 如果创建虚拟环境时不选择指定的python版本, 那么虚拟环境创建后默认就是系统默认的python版本. 比如如果系统还有一个python3.6.1, 路径为: /usr/local/python3/bin/python3 [root@kevin-test pj_test]# /usr/local/python3/bin/python3 -V Python 3.6.1 则创建虚拟机时选择指定的python版本 [root@kevin-test project_test]# Virtual env --no-site-packages -p /usr/local/python3/bin/python3.6.1 pj_test [root@kevin-test project_test]# cd pj_test/ [root@kevin-test pj_test]# source ./bin/activate (pj_test) [root@kevin-test pj_test]# python -V Python 3.6.1 可以在服务器上提前安装多个版本的python环境, 不同版本的python的二进制路径不一样 然后在使用 Virtual env创建各个项目的虚拟环境时指定不同的python版本, 这样各个项目python解释器环境就实现了相互隔离, 非常纯净! 使用"deactivate" 命令退出或停用虚拟环境: [root@kevin-test project_test]# cd pj_test/ [root@kevin-test pj_test]# source ./bin/activate (pj_test) [root@kevin-test pj_test]# python -V Python 2.7.5 (pj_test) [root@kevin-test pj_test]# deactivate [root@kevin-test pj_test]# 退出虚拟环境后, 此时就回到了正常的环境,现在pip或python均是在系统Python环境下执行。 退出虚拟环境后, 之前在虚拟环境里的部署的应用程序的使用都不会受到影响! 完全可以针对每个应用创建独立的Python运行环境,这样就可以对每个应用的Python环境进行隔离。 如果要删除一个虚拟环境, 只需删除它的虚拟目录即可, 比如要删除虚拟环境pj_test, 则: [root@kevin-test pj_test]# rm -rf /opt/project_test/pj_test/
在虚拟环境安装 Python packages
Virtual env 附带有pip安装工具,因此需要安装的packages可以直接运行: (pj_test) [root@kevin-test pj_test]# pip install [套件名称] (pj_test) [root@kevin-test pj_test]# pip -V pip 18.1 from /opt/project_test/pj_test/lib/python2.7/site-packages/pip (python 2.7) (pj_test) [root@kevin-test pj_test]# pip install jinja2 安装后, 可以在虚拟环境里找到这个套件 (pj_test) [root@kevin-test pj_test]# ll -d /opt/project_test/pj_test/lib/python2.7/site-packages/jinja2/ drwxr-xr-x 2 root root 4096 Dec 17 18:26 /opt/project_test/pj_test/lib/python2.7/site-packages/jinja2/ 在虚拟环境下,用pip安装的包都被安装到对应虚拟的这个环境下,系统Python环境不受任何影响。 也就是说,虚拟环境是专门针对具体的某个应用创建的。 [root@kevin-test ~]# pip -V pip 18.1 from /usr/lib/python2.7/site-packages/pip (python 2.7) 如果没有启动虚拟环境,系统环境也安装了pip工具,那么packages将被安装在系统环境中. 为了避免发生此事,可以在~/.bashrc文件中加上 (最好添加下面的内容): [root@kevin-test ~]# vim ~/.bashrc export PIP_REQUIRE_ Virtual ENV=true 使配置生效 [root@kevin-test ~]# source ~/.bashrc 如果在没开启虚拟环境时, 在虚拟环境之外的系统上运行pip,就会提示错误:"Could not find an activated Virtual env (required)".
如上安装好 Virtual env之后, 就可以解决python版本冲突问题和python库不同版本的问题了!!
Virtual env 用法小总结
1) 创建环境 Virtual env [新环境名] :这会再当前目录下创建一个新环境目录 可使用 Virtual env --help 来查看如何使用。可以使用参数 --python=/usr/bin/python3 来创建一个已经安装的的Python环境。 2) 使用环境 切换到项目的新环境目录 执行:source ./bin/activate 来激活环境,激活后在命令行的前面会出现新环境名称 接下来可使用pip命令安装新环境需要的各种包。(pip命令在创建新环境时自带) 3) 退出虚拟环境 deactivate 如果要删除虚拟环境,只需退出虚拟环境后,删除对应的虚拟环境目录即可。不影响其他环境。 4) 注意事项 如果没有启动虚拟环境,系统也安装了pip工具,那么套件将被安装在系统环境中,为了避免发生此事,可以在~/.bashrc文件中加上:export PIP_REQUIRE_ Virtual ENV=true 或者让在执行pip的时候让系统自动开启虚拟环境:export PIP_REQUIRE_ Virtual ENV=true 5) 保证环境一致性 用pip freeze查看当前安装版本 [root@kevin-test ~]# pip freeze 另外: [root@kevin-test ~]# pip freeze > requirements.txt 这将会创建一个 requirements.txt 文件,其中包含了当前环境中所有包及 各自的版本的简单列表。 可以使用 "pip list"在不产生requirements文件的情况下, 查看已安装包的列表。 这将会使另一个不同的开发者(或者是你本人,如果你本人需要重新创建这样的环境) 在以后安装相同版本的相同包变得容易。 将这个requirements.txt拷贝到新的机器环境下执行: # pip install -r requirements.txt 这能帮助确保安装、部署和开发者之间的一致性。
虚拟环境管理工具 - Virtual envwrapper Virtual env使用起来不是很方便,因为 Virtual 的启动、停止脚本都在特定目录,可能一段时间后,你可能会有很多个虚拟环境散落在系统各处,你可能忘记它们的名字或者位置。鉴于 Virtual env不便于对虚拟环境集中管理,所以推荐直接使用 Virtual envwrapper。 Virtual envwrapper提供了一系列命令使得和虚拟环境工作变得便利。它把你所有的虚拟环境都放在一个地方。
Virtaulenvwrapper是 Virtual env的扩展包,用于更方便管理虚拟环境,它可以做: - 将所有虚拟环境整合在一个目录下; - 管理(新增,删除,复制)虚拟环境; - 切换虚拟环境等等. 安装 Virtual envwrapper (确保 Virtual env已提前安装) [root@kevin-test ~]# pip install Virtual envwrapper Could not find an activated Virtual env (required). 如果出现上面的报错:"Could not find an activated Virtual env (required)." 解决办法: 打开~/.bashrc文件, 添加下面的内容 [root@kevin-test ~]# vim ~/.bashrc export PIP_REQUIRE_ Virtual ENV=true [root@kevin-test ~]# source ~/.bashrc 然后接着安装 Virtual envwrapper [root@kevin-test ~]# pip install Virtual envwrapper 如果还是出现上面的那个报错:"Could not find an activated Virtual env (required)." 接着执行下面命令(~/.bashrc文件里设置该参数为true, 确保pip安装的包在虚拟环境下; 虚拟环境之外的系统里执行pip时, 每次需要手动source 这个参数的false值) [root@kevin-test ~]# export PIP_REQUIRE_ Virtual ENV=false 最后再次安装 Virtual envwrapper即可 [root@kevin-test ~]# pip install Virtual envwrapper Collecting Virtual envwrapper Using cached https://files.pythonhosted.org/packages/2b/8c/3192e10913ad945c0f0fcb17e9b2679434a28ad58ee31ce0104cba3b1154/ Virtual envwrapper-4.8.2-py2.py3-none-any.whl Requirement already satisfied: Virtual env-clone in /usr/lib/python2.7/site-packages/ Virtual env_clone-0.4.0-py2.7.egg (from Virtual envwrapper) (0.4.0) Requirement already satisfied: stevedore in /usr/lib/python2.7/site-packages/stevedore-1.30.0-py2.7.egg (from Virtual envwrapper) (1.30.0) Requirement already satisfied: Virtual env in /usr/lib/python2.7/site-packages (from Virtual envwrapper) (16.1.0) Requirement already satisfied: pbr!=2.1.0,>=2.0.0 in /usr/lib/python2.7/site-packages/pbr-5.1.1-py2.7.egg (from stevedore-> Virtual envwrapper) (5.1.1) Requirement already satisfied: six>=1.10.0 in /usr/lib/python2.7/site-packages/six-1.12.0-py2.7.egg (from stevedore-> Virtual envwrapper) (1.12.0) Installing collected packages: Virtual envwrapper Successfully installed Virtual envwrapper-4.8.2 默认 Virtual envwrapper安装在下面python解释器中的site-packages,实际上需要运行 Virtual envwrapper.sh文件才行; 所以要查找出安装的 Virtual envwrapper.sh执行文件 [root@kevin-test ~]# find / -name Virtual envwrapper* /usr/bin/ Virtual envwrapper.sh /usr/bin/ Virtual envwrapper_lazy.sh /usr/lib/python2.7/site-packages/ Virtual envwrapper-4.8.2-py2.7-nspkg.pth /usr/lib/python2.7/site-packages/ Virtual envwrapper /usr/lib/python2.7/site-packages/ Virtual envwrapper-4.8.2.dist-info 此时还不能使用 Virtual envwrapper,每次要想使用 Virtual envwrapper 工具时,都必须先激活 Virtual envwrapper.sh文件才行, 另外,如果创建前要将即将的环境保存到虚拟环境中,就要先设置一下环境变量 设置环境变量 [root@kevin-test ~]# export WORKON_HOME=~/Envs 创建虚拟环境管理目录. 即创建的虚拟环境都会放到上面设置的~/Envs目录下面 [root@kevin-test ~]# mkdir -p $WORKON_HOME 在~/.bashrc文件里配置环境变量, 添加下面两行 第一行表示: 存放虚拟环境目录 第二行表示: virtrualenvwrapper.sh执行文件的路径 [root@kevin-test ~]# vim ~/.bashrc export WORKON_HOME=~/Envs source /usr/bin/ Virtual envwrapper.sh 使得以上环境变量的配置生效 [root@kevin-test ~]# source ~/.bashrc 现在开始使用 Virtual envwrapper 管理虚拟机 (可以删除上面之前创建的虚拟环境/opt/project_test/pj_test 了, 后续都将使用 Virtual envwrapper创建和管理虚拟环境) a) 使用mk Virtual env 命令创建虚拟环境 创建一个虚拟环境, 虚拟机名称为project_kevin: [root@kevin-test ~]# mk Virtual env project_kevin New python executable in /root/Envs/project_kevin/bin/python2 Also creating executable in /root/Envs/project_kevin/bin/python Installing setuptools, pip, wheel... done. Virtual envwrapper.user_scripts creating /root/Envs/project_kevin/bin/predeactivate Virtual envwrapper.user_scripts creating /root/Envs/project_kevin/bin/postdeactivate Virtual envwrapper.user_scripts creating /root/Envs/project_kevin/bin/preactivate Virtual envwrapper.user_scripts creating /root/Envs/project_kevin/bin/postactivate Virtual envwrapper.user_scripts creating /root/Envs/project_kevin/bin/get_env_details (project_kevin) [root@kevin-test ~]# 再创建另一个虚拟机, 虚拟机名称为project_bobo (project_kevin) [root@kevin-test ~]# deactivate //先退出上面的那个虚拟环境 [root@kevin-test ~]# mk Virtual env --no-site-packages project_bo //这里加上了参数--no-site-packages New python executable in /root/Envs/project_bo/bin/python2 Also creating executable in /root/Envs/project_bo/bin/python Installing setuptools, pip, wheel... done. Virtual envwrapper.user_scripts creating /root/Envs/project_bo/bin/predeactivate Virtual envwrapper.user_scripts creating /root/Envs/project_bo/bin/postdeactivate Virtual envwrapper.user_scripts creating /root/Envs/project_bo/bin/preactivate Virtual envwrapper.user_scripts creating /root/Envs/project_bo/bin/postactivate Virtual envwrapper.user_scripts creating /root/Envs/project_bo/bin/get_env_details (project_bo) [root@kevin-test ~]# ==================================================== 还可以选择指定的python版本进行虚拟环境的创建, 不过指定的python版本必须要提前安装好, 比如 # mk Virtual env project_hui --python=python3.6.1 # mk Virtual env project_hui --python=/usr/local/python3/bin/python3.6.1 ==================================================== 创建的虚拟环境的项目目录都放在了上面设置的环境变量目录~/Envs下面 [root@kevin-test ~]# ll -d ~/Envs/project_kevin/ drwxr-xr-x 5 root root 56 Dec 17 22:27 /root/Envs/project_kevin/ [root@kevin-test ~]# ll -d ~/Envs/project_bo/ drwxr-xr-x 5 root root 56 Dec 17 22:28 /root/Envs/project_bo/ b) 使用workon 或者 ls Virtual env 命令列出虚拟环境列表 [root@kevin-test ~]# workon project_bo project_kevin 或者 [root@kevin-test ~]# ls Virtual env project_bo ========== project_kevin ============= c) 使用workon 启动/切换虚拟环境 [root@kevin-test ~]# workon project_bo (project_bo) [root@kevin-test ~]# python -V Python 2.7.5 (project_bo) [root@kevin-test ~]# 创建一个项目,它会创建虚拟环境,并在 $WORKON_HOME 中创建一个项目目录。 当您使用 "workon 项目的虚拟环境名称" 时,它会自动cd -ed 到项目目录中。 d) 使用deactivate命令退出/离开虚拟环境,和virutalenv一样的命令 [root@kevin-test ~]# workon project_bo (project_bo) [root@kevin-test ~]# python -V Python 2.7.5 (project_bo) [root@kevin-test ~]# deactivate [root@kevin-test ~]# e) 使用rm Virtual env 命令 删除虚拟环境 [root@kevin-test ~]# ls Virtual env project_bo ========== project_kevin ============= [root@kevin-test ~]# rm Virtual env project_bo Removing project_bo... [root@kevin-test ~]# ls Virtual env project_kevin ============= f) 使用lssitepackages命令显示 site-packages 目录中的内容。 [root@kevin-test ~]# workon project_kevin (project_kevin) [root@kevin-test ~]# lssitepackages easy_install.py pip pkg_resources setuptools-40.6.3.dist-info wheel-0.32.3.dist-info easy_install.pyc pip-18.1.dist-info setuptools wheel g) 使用cd Virtual env命令导航到当前激活的虚拟环境的目录中,比如说这样就能够浏览它的site-packages。 [root@kevin-test ~]# workon project_kevin (project_kevin) [root@kevin-test site-packages]# cd Virtual env (project_kevin) [root@kevin-test project_kevin]# ls bin include lib lib64 h) 使用cdsitepackages命令直接进入到 site-packages 目录中, 和上面的cd Virtual env 类似 [root@kevin-test ~]# workon project_kevin (project_kevin) [root@kevin-test ~]# cdsitepackages (project_kevin) [root@kevin-test site-packages]# ls easy_install.py pip pkg_resources setuptools-40.6.3.dist-info wheel-0.32.3.dist-info easy_install.pyc pip-18.1.dist-info setuptools wheel ============================================= 为了方便运维管理, 可以进行一些别名设置, 如下: [root@kevin-test ~]# vim ~/.bashrc # Virtual env alias vte=' Virtual env' alias mkvte='mk Virtual env' alias deact='deactivate' alias rmvte='rm Virtual env' alias lsvte='ls Virtual env' alias won='workon' 使得上面配置生效 [root@kevin-test ~]# source ~/.bashrc 使用别名进行操作 [root@kevin-test ~]# lsvte project_kevin ============= [root@kevin-test ~]# won project_kevin (project_kevin) [root@kevin-test ~]# deact [root@kevin-test ~]# rmvte project_kevin Removing project_kevin... [root@kevin-test ~]# lsvte [root@kevin-test ~]#
Virtual env使用时遇到的一个坑点, 经常排查验证, 得出结论如下:
1) root用户和普通用户都可以创建虚拟环境(比如虚拟环境名称为venv),venv虚拟环境的相关文件和文件夹的owner都是该用户, 如果是非root的其他用户激活该venv虚拟环境的话,会因为文件权限的问题导致python库安装失败!! 所以说: 非root用户不要去激活使用其他用户创建的venv虚拟环境! 2) 一旦以用户A的身份激活venv虚拟环境后,在虚拟环境中就不能再通过su命令切换其他用户,否则会自动退出虚拟环境! 所以说: 在虚拟环境中不要通过su切换用户! 3) 以用户A的身份激活某venv虚拟环境后,在虚拟环境中所有通过"sudo + cmd"执行的命令,都等同于在虚拟环境外执行。 所以说: 在虚拟环境中不要通过sudo执行命令 以上提到的3个小问题,在使用 Virtual env的时候一定要注意。
查看更多关于Python虚拟环境工具-Virtualenv 介绍及部署记录的详细内容...