python virtualenv

来源:互联网 发布:淄博最专业的seo公司 编辑:程序博客网 时间:2024/04/20 08:51

在使用virtualenv之前,可以先从这篇文章了解起来:

https://virtualenv-chinese-docs.readthedocs.io/en/latest/#


一、什么是virtualenv

virtualenv可创建隔离的Python开发环境,用于解决依赖、版本以及间接权限,它是workingenvvitrual-python的扩展。

1)不同的virtualenv环境隔离,每个环境都有独立安装目录

2)可以通过像--python的这种命令来更改解释器的版本

3)开发可以在不同的virtualenv环境下工作、部署、测试,并且不受当前系统限制

virtualenv官网介绍:https://virtualenv.pypa.io/en/stable/


二、构建virtualenv隔离环境:

该构建操作是基于CentOS建立的,可通过搭建虚拟机实现。

S1、构建基础ENV环境,执行命令:virtualenv ENV

该操作会创建 ENV/lib/pythonX.X/site-packages 目录 和 ENV/bin/python , 前者用来存放要安装的模块,后者就是隔离环境的Python解释器。 在virtualenv环境下使用此解释器(包括以 #!/path/to/ENV/bin/python 开头的脚本)时,使用的都是隔离环境下的模块。

(此外可更改setuptoolsdistribute的使用)

S2、进入ENV,激活ENV环境,执行命令:source bin/activate

激活之后,系统的环境变量会有所改变,如下所示:

[root@localhost ENV]# echo $PATH/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/lanyyyy/.local/bin:/home/lanyyyy/bin[root@localhost ENV]# source bin/activate(ENV) [root@localhost ENV]# echo $PATH/home/lanyyyy/workspace/ENV/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/lanyyyy/.local/bin:/home/lanyyyy/bin

可以看到,激活环境会有前缀(ENV),便于你区分当前的环境使用。如果想禁用的话,在执行activate前对 VIRTUAL_ENV_DISABLE_PROMPT赋任意值即可。

S3、再构建一个ENV1环境,并且使用pip在不同的环境安装tox,可以看到:

(ENV1) [root@localhost ENV1]# pip list | grep toxDEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.tox (2.7.0)# tox的2.7.0版本(ENV1) [root@localhost ENV1]# deactivate[root@localhost ENV1]# cd ../ENV[root@localhost ENV]# source bin/activate(ENV) [root@localhost ENV]# pip list | grep toxDEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.tox (2.8.1)# tox的2.8.1版本


可以看到,不同的ENV可以使用不同的版本。

S4、最后,退出virtualenv环境:

deactivate

 

三、其它一些功能或参数:

1)这里需要强调的是,在使用virtualenv命令的时候,需要加上目标路径。

2)可以使用avtivate_this更改解释器的路径(没太理解,可能需要具体场景分析)

3)重新定位隔离环境(也没太明白)

4)指定不同的python解释器构建virtualenv环境:

 

四、virtualenvwrapper

virtualenvwrappervirtualenv的扩展包,用于更加方便管理虚拟环境,包括:

(1)将所有虚拟环境整合在一个目录上;

(2)管理(新增、删除、复制)虚拟环境

(3)快速切换虚拟环境

具体的使用执行方式如下:

pip install virtualenvwrappermkdir ~/.virtualenvsexport WORKON_HOME=~/.virtualenvs# 可以添加到~/.bashrcsource /usr/bin/virtualenvwrapper.sh# 该路径要查看环境的具体路径

查看virtualenvwrapper的命令:

 [root@localhost workspace]# virtualenvwrapper --helpvirtualenvwrapper is a set of extensions to Ian Bicking's virtualenvtool.  The extensions include wrappers for creating and deletingvirtual environments and otherwise managing your development workflow,making it easier to work on more than one project at a time withoutintroducing conflicts in their dependencies.For more information please refer to the documentation:    http://virtualenvwrapper.readthedocs.org/en/latest/command_ref.htmlCommands available:  add2virtualenv: add directory to the import path#  allvirtualenv: run a command in all virtualenvs# 显示所有虚环境  cdproject: change directory to the active project# 更换目录  cdsitepackages: change to the site-packages directory# 进入虚环境库目录  cdvirtualenv: change to the $VIRTUAL_ENV directory# 进入虚环境目录  cpvirtualenv: duplicate the named virtualenv to make a new one# 复制生成一个新的  lssitepackages: list contents of the site-packages directory# 显示库  lsvirtualenv: list virtualenvs# 显示虚环境  mkproject: create a new project directory and its associated virtualenv# 创建目录  mktmpenv: create a temporary virtualenv  mkvirtualenv: Create a new virtualenv in $WORKON_HOME# 创建virtualenv  rmvirtualenv: Remove a virtualenv# 删除env  setvirtualenvproject: associate a project directory with a virtualenv  showvirtualenv: show details of a single virtualenv  toggleglobalsitepackages: turn access to global site-packages on/off  virtualenvwrapper: show this help message  wipeenv: remove all packages installed in the current virtualenv  workon: list or change working virtualenvs# 显示当前工程

这些命令简化了virtualenv的使用。

其他命令比如: virtualenv-burritoautoenv

 

五、virtualenv代码解析:

S1、在执行virtualenv构建环境的时候,调用的是/usr/bin/virtualenv命令:

#!/usr/bin/python                                                                                                  # -*- coding: utf-8 -*-                                                import re                                                              import sys                                                                        from virtualenv import main                                                                                                  if __name__ == '__main__':                                                 sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])      sys.exit(main())                                      

S2、查看main函数的详情/usr/lib/python2.7/site-packages/virtualenv.py

def main():                                                                                         ...(略)    create_environment(home_dir,         # 构建环境                                                         site_packages=options.system_site_packages,                                clear=options.clear,                                                       unzip_setuptools=options.unzip_setuptools,                                 prompt=options.prompt,                                                     search_dirs=options.search_dirs,                                           download=options.download,                                                 no_setuptools=options.no_setuptools,                                       no_pip=options.no_pip,                                                     no_wheel=options.no_wheel,                                                 symlink=options.symlink)                            ...(略)


S3、环境构建函数:create_environment()

def create_environment(home_dir, site_packages=False, clear=False,                                unzip_setuptools=False,                                                    prompt=None, search_dirs=None, download=False,                             no_setuptools=False, no_pip=False, no_wheel=False,                         symlink=True):                                          """                                                                        Creates a new environment in ``home_dir``.                                                                                                            If ``site_packages`` is true, then the global ``site-packages/``           directory will be on the path.                                                                                                                        If ``clear`` is true (default False) then the environment will             first be cleared.                                                          """                                                                        home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)     # 构建虚环境目录                                                                               py_executable = os.path.abspath(install_python(               # 构建执行函数        home_dir, lib_dir, inc_dir, bin_dir,                                       site_packages=site_packages, clear=clear, symlink=symlink))                                                                                       install_distutils(home_dir)                                 # 构建distutils                                                                                          to_install = []                                                                                                                                       if not no_setuptools:                                                          to_install.append('setuptools')                                                                                                                   if not no_pip:                                                         
                            

S4、查看激活函数avtivate

# This file must be used with "source bin/activate" *from bash*             # you cannot run it directly                                                                                                                            deactivate () {                                        # 解除activate环境                         unset -f pydoc >/dev/null 2>&1                                                                                                                          # reset old environment variables                                           # ! [ -z ${VAR+_} ] returns true if VAR is declared at all                  if ! [ -z "${_OLD_VIRTUAL_PATH+_}" ] ; then                                     PATH="$_OLD_VIRTUAL_PATH"                                                   export PATH                                                                 unset _OLD_VIRTUAL_PATH                                                 fi                                                                          if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then                               PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"                                       export PYTHONHOME                                                           unset _OLD_VIRTUAL_PYTHONHOME                                           fi                                                                                                                                                      # This should detect bash and zsh, which have a hash command that must      # be called to get it to forget past commands.  Without forgetting          # past commands the $PATH changes we made may not be respected              if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then                         hash -r 2>/dev/null                                                     fi                                                                                                                                                      if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then                                      PS1="$_OLD_VIRTUAL_PS1"                                                     export PS1                                                                  unset _OLD_VIRTUAL_PS1                                                  fi                                                                              unset VIRTUAL_ENV                                             if [ ! "${1-}" = "nondestructive" ] ; then                    # Self destruct!                                                  unset -f deactivate                                       fi                                                        }                                                                                                                           # unset irrelevant variables                                  deactivate nondestructive                                                                                                   VIRTUAL_ENV="/home/lanyyyy/workspace/ENV"       # 当前该环境的目录              export VIRTUAL_ENV                              # 导入工作目录                                                                            _OLD_VIRTUAL_PATH="$PATH"                      # 备份旧目录               PATH="$VIRTUAL_ENV/bin:$PATH"                   # 新增virtualenv目录              export PATH                                                                                                                 # unset PYTHONHOME if set                                     if ! [ -z "${PYTHONHOME+_}" ] ; then                              _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"  # 备份PYTHONHOME                       unset PYTHONHOME                                          fi                                                                                                                          if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then     # 虚环境提示符设置           _OLD_VIRTUAL_PS1="$PS1"                    # PS1为linux的提示符                  if [ "x" != x ] ; then                                            PS1="$PS1"                                                else                                                              PS1="(`basename \"$VIRTUAL_ENV\"`) $PS1"                  fi                                                            export PS1                                   # 更新环境提示符                       fi                                                                                                                                              # Make sure to unalias pydoc if it's already there                      alias pydoc 2>/dev/null >/dev/null && unalias pydoc     # 这块为什么取消暂不理解?                                                                                        pydoc () {                                                                  python -m pydoc "$@"                         # 使用pydoc显示模块详情                       }                                                                                                                                               # This should detect bash and zsh, which have a hash command that must  # be called to get it to forget past commands.  Without forgetting      # past commands the $PATH changes we made may not be respected          if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then                     hash -r 2>/dev/null                            # 清除hash记录的命令                     fi   

                                           

#  不使用hash清除的话,比如调用tox命令,如果之前执行过,那么在hash中会有所记录,下次执行时,就会直接读取hash执行到系统tox,而不会根据PATH重新搜索到virtualenv环境中安装的tox。                        

#  此外,使用man hash还可以看到系统的内置命令                                                                      

 

六、关于virtualenv

基于微服务背景下的多服务部署,涉及很多内在的问题,比如各个服务之间的部署环境隔离、使用不同的版本等等。针对具体情况可能涉及:docker部署隔离(使用最多)、代码打包成不同RPM部署到不同目录下、virtual虚环境部署、mock环境隔离等。从使用来讲,virtualenv是非常简单,构建迅速,并且部署简单。

但是仍会有很多缺点,如果对virtualenv感兴趣的话,可以读一下这篇文章:

https://pythonrants.wordpress.com/2013/12/06/

其中存在的一些有趣的观点:

(1)virtualenv只提供python层面的隔离,如果软件包依赖了系统层级的东西,这种隔离是不可重入的;

(2)有更多的系统级别的隔离方案可选:比如虚拟机、LXC(容器)技术;

(3)virtualenv的部署是反模式的,只是更新了PYTHONPATH的路径,并没有对系统的完全控制权;

(4)pipvirtualenv只能从源码进行构建

(5)混乱的hack:在具体的虚环境下运行时需要硬编码,并且很难在虚环境外调试;

(6)pip freeze的滥用:pip freeze会给出当前所有python软件列表,但该列表过于冗余和复杂。如果你想得到一个干净的运行依赖,你必须重新构建应用、寻找依赖,但很耗时。

 

七、其它:

1pipvirtualenv的作者是Lan Bicking,感兴趣的可以了解下:

http://www.ianbicking.org/blog/

原创粉丝点击