• Python多环境管理神器(pipenv)


    pipenv

    参考官网:https://pipenv.pypa.io/

    pipenv 是一款比较新的包管理工具,其借鉴了 javascript 的 npm 和 PHP 的 composer 等理念,通过一个依赖描述文件 Pipfile 来安装和管理依赖,以达到协同开发的目的。如果你熟悉 npm 或者 composer 的话,那 pipenv 正合你胃口。pipenv 其实整合了 pip 和 virtualenv 等库,在其上推出了更便捷的使用方式。

    1、安装pipenv

    直接使用pip命令安装

    pip3 install pipenv 

    设置命令行的自动补全功能

    如果使用的bash shell,请将以下代码添加到 .bashrc 或 .bash_profile 文件内:

    eval "$(pipenv --completion)" 

    参考:https://blog.csdn.net/swinfans/article/details/89305301

    命令详解:

    $ pipenv
    Usage: pipenv [OPTIONS] COMMAND [ARGS]...
    
    Options:
      --where             输出项目根目录相关信息
      --venv              输出virtualenv相关信息
      --py                输出Python解释器相关信息
      --envs              输出环境变量选项
      --rm                删除virtualenv
      --bare              最小化输出
      --completion        命令自动补全
      --man               显示man页面
      --three / --two     在创建virtualenv时使用Python3或Python2
      --python TEXT       指定创建virtualenv时使用的具体的Python版本
      --site-packages     为virtualenv启用site-packages [env变量:PIPENV_SITE_PACKAGES]
      --clear             清除缓存(pipenv,pip和pip-tools)[env变量:PIPENV_CLEAR]
      --pypi-mirror TEXT  指定一个PyPI镜像
      --version           显示版本信息并退出
      -h, --help          显示帮助信息并退出
    
    
    使用示例:
       创建一个项目,并明确指定使用Python3.7:
       $ pipenv --python 3.7
    
       删除项目的virtualenv (inferred from current directory):
       $ pipenv --rm
    
       为项目安装所有依赖项 (including dev):
       $ pipenv install --dev
    
       创建包含pre-releases的lockfile文件:
       $ pipenv lock --pre
    
       将已安装的依赖项显示为图表:
       $ pipenv graph
    
       检查已安装的依赖项是否存在安全漏洞:
       $ pipenv check
    
       安装一个本地的setup.py到你的虚拟环境或Pipfile:
       $ pipenv install -e .
    
       使用原生的pip命令:
       $ pipenv run pip freeze
    
    Commands:
      check      根据 Pipfile 中提供的PEP 508标记检查安全漏洞
      clean      卸载所有 Pipfile.lock 未指定的包
      graph      显示当前安装的依赖项的关系图信息
      install    如果未指定要安装的包,则会安装 Pipfile 中的所有包,否则,只安装指定的包
      lock       生成 Pipfile.lock 文件
      open       在编辑器中查看给定的模块
      run        运行virtualenv中已安装的命令
      shell      在virtualenv内启动一个shell
      sync       安装 Pipfile.lock 中指定的所有的包
      uninstall  卸载一个指定的包并将其从 Pipfile 中移除
      update     先运行lock命令,在运行sync命令

    2、pipenv虚拟环境管理

    2.1、虚拟环境创建与激活

    创建虚拟环境

    # 进入项目目录:
    [root@ops-130 data]# mkdir myproj10
    [root@ops-130 data]# cd myproj10/
    [root@ops-130 myproj10]# ls
    [root@ops-130 myproj10]# pipenv install

    上面的命令会自动在~/.local/share/virtualenvs/目录下创建虚拟环境目录,

    名字为一个当前目录名加一串随机字符串的虚拟环境目录。这里是myproj10-740tHe3W

    创建过程如下图:

    clipboard

    下面多了两个文件,为Pipfile和Pipfile.lock,用于存放依赖包名的文件。

    类似php里的composer.json和composer.lock。

    [root@ops-130 myproj10]# ls
    Pipfile  Pipfile.lock

    查看虚拟环境

    [root@ops-130 myproj10]# pipenv --venv
    /root/.virtualenvs/myproj10-740tHe3W

    我们的虚拟环境目录在/root/.virtualenvs/下面,是因为我们之前设置过环境变量

    export WORKON_HOME=$HOME/.virtualenvs 

    激活虚拟环境:

    cd /data/myproj10
    pipenv shell

    激活后如下图:

    clipboard

    注意:上面激活虚拟环境的时候,出现了这么一个告警:

    Warning: Your Pipfile requires python_version 2.7, but you are using 3.9.9 (/root/./m/bin/python).

    原因:这是因为创建虚拟环境的时候,没有指定python解释器,Pipfile就使用系统默认的python解释器了,就是2.7.5,但是pipenv却是使用系统最新的解释器3.9.

    解决办法:

    办法一:手动修改Pipfile

    手动修改Pipfile文件里的python_version

    注意:Pipfile.lock里的也要修改

    vim Pipfile
    
    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"
    
    [packages]
    
    [dev-packages]
    
    [requires]
    python_version = "3.9"

    办法二:删除虚拟环境,重新创建虚拟环境

    删除虚拟环境后,再次安装会覆盖之前的Pipfile,使用新环境。如果不删除,无法覆盖。

    # pipenv --rm删除当前虚拟环境,注意Pipfile不会被删掉
    [root@ops-130 myproj10]# pipenv --rm
    # 使用pipenv重新安装,指定解释器版本为3.X
    [root@ops-130 myproj10]# pipenv install --three
    # 此时再次查看Pipfile版本就和环境一致了。
    [root@ops-130 myproj10]# cat Pipfile

    如下图:

    clipboard

    退出虚拟环境:exit

    ((myproj10) ) [root@ops-130 myproj10]# exit
    exit
    [root@ops-130 myproj10]#

    刚创建好虚拟环境的时候,会自动进入虚拟环境,并且此时是没有前缀显示,此时需要用exit退出。

    当后面用pipenv shell激活的时候,会显示前缀,此时可以用exit退出,也可以使用deactivate退出。

    clipboard

    删除虚拟环境

    [root@ops-130 myproj10]# pipenv --rm 
    Removing virtualenv (/root/.virtualenvs/myproj10-740tHe3W)...

    2.2、创建虚拟环境的多种方式

    pipenv创建虚拟环境有多种方式,这里总结一下:

    方式一:指定解释器创建虚拟环境

    # 创建虚拟环境
    pipenv --three
    # 或者
    pipenv --python 3.9

    这种方式是指定python解释器,并创建虚拟环境。

    它会在当前目录生成Pipfile,不会生成Pipfile.lock

    这种方式创建虚拟环境后,会自动进入虚拟环境,但是进入后也不会显示前缀

    clipboard

    方式二:安装所有依赖时创建虚拟环境

    # 创建虚拟环境
    pipenv install

    这种方式是在安装依赖包的同时创建虚拟环境。

    因为pipenv install,就是根据Pipfile来安装所有依赖,类似npm install

    如果当前目录没有Pipfile,它就会自动创建Pipfile并创建虚拟环境。

    因为这种方式它已经在安装所有依赖了,所以不仅会创建Pipfile,也会创建Pipfile.lock文件。

    同时,它创建虚拟环境后,也会自动进入环境,但是也不会显示前缀。

    如下图:

    clipboard

    方式三:激活时创建虚拟环境

    # 激活,如果环境不存在,则创建虚拟环境并激活
    pipenv shell

    这个命令主要用于激活环境,但是如果环境不存在,则会先创建虚拟环境,并同时激活虚拟环境。

    这种方式因为使用了pipenv shell激活了,所以创建虚拟环境后,也会自动进入虚拟环境,并激活。

    会显示虚拟环境前缀。

    如下图:

    clipboard

    2.3、修改虚拟环境目录位置

    有三种方法:

    方法一:

    # 方法一:
    # 设置这个环境变量,pipenv会在当前目录下创建.venv的目录,以后都会把模块装到这个.venv下。
    export PIPENV_VENV_IN_PROJECT=1

    方法二:

    # 自己在项目目录下手动创建.venv的目录,然后运行 pipenv run 或者 pipenv shell pipenv都会在.venv下创建虚拟环境。
    mkdir .venv
    pipenv shell

    方法三:

    # 设置WORKON_HOME到其他的地方 (如果当前目录下已经有.venv,此项设置失效)。
    export WORKON_HOME=$HOME/.virtualenvs

    注意:

    小技巧: 如果子级目录的父级目录已经创建过虚拟环境, 则子级目录无法创建虚拟目录(子级目录无法生成Pipfile, 子级默认会使用父级的虚拟环境), 如果确实需要在子级目录创建独立的虚拟环境,可以运行pipenv --where 获取父级虚拟环境的名字, 根据虚拟环境的前半部分名字, 确定父级目录的位置, 然后删除父级目录下的Pipfile, Pipfile.lock, 运行exit退出父级虚拟环境,然后回到子目录,运行pipenv --three创建子目录的虚拟环境即可

    2.4、相关定位操作

    定位项目目录:

    [root@ops-130 aaa]# pipenv --where
    /data/myproj10

    定位虚拟环境目录,即virtualenv目录

    [root@ops-130 aaa]# pipenv --venv
    /root/.virtualenvs/myproj10-740tHe3W

    定位Python解释器:

    [root@ops-130 aaa]# pipenv --py
    /root/.virtualenvs/myproj10-740tHe3W/bin/python

    如下图:

    clipboard

    3、pipenv包管理

    安装依赖包:

    安装相关依赖包,并加入到Pipfile

    pipenv install flask

    它会在当前环境安装flask依赖包,并记录flask包名以及版本信息,记录到Pipfile里。

    如果安装的时候,没有指定包名,默认是最新的,会记录为“*”

    注意:Pipfile只会记录你install里指定的包,但是这个flask包本身所依赖的包不会记录,

    但是所有的依赖详情都会记录到Pipfile.lock中。

    clipboard

    Pipfile.lock类似如下:

    clipboard

    查看目前安装的库及其依赖关系

    pipenv graph

    如下图:这是所有的完整依赖关系,这些会记录在Pipfile.lock中。

    clipboard

    Pipfile会记录当前虚拟环境安装的所有依赖包及其对应的版本,当我们需要迁移项目,部署新项目,或者有新人接手时,就可以直接拿到这个Pipfile和Pipfile.lock文件,直接pipenv install即可,它就会按照Pipfile里的包,把所有的依赖文件都安装上,是不是很方便。

    安装所有依赖包:

    # 根据Pipfile的记录,安装所有依赖包
    pipenv install

    指定安装包版本:

    你可以使用 语义化(https://semver.org/)的版本控制方案 指定包的版本。例如 major.minor.micro 。

    例如,你可以使用如下的命令安装 requests:

    pipenv install requests~=1.2   # 相当于 requests~=1.2.0

    Pipenv 将安装 1.2 版本和任何 minor 版本的更新,但不会安装 2.0 版本。

    上面的命令将会自动更新 Pipfile 文件以体现这个特殊的需求。

    通常,Pipenv使用与pip相同的参数格式。但是,请注意,根据PEP 440,您不能使用包含连字符或加号的版本号。

    要指定包含或者排除具体的版本,您可以使用如下命令:

    pipenv install "requests>=1.4"   # 只安装等于或者大于 1.4.0 的版本
    pipenv install "requests<=2.13"  # 只安装小于或者等于 2.13.0 的版本
    pipenv install "requests>2.19"   # 安装 2.19.1 版本但是不安装 2.19.0 版本

    注意:强烈建议使用双引号包裹包名和版本号以避免unix操作系统中的输入和输出重定向问题。

    请优先使用 ~= 标识符而不是 == 标识符,因为后者会阻止 pipenv 更新包:

    pipenv install "requests~=2.2"  # 锁定包的主版本(这相当于使用==2.*)

    要避免安装某个特定的版本,可以使用 != 标识符。

    要深入解释有效标识符和更复杂的用例,请查看 PEP-440 的相关部分。

    https://www.python.org/dev/peps/pep-0440/#version-specifiers%3E

    卸载依赖包:

    卸载指定包:

    pipenv uninstall flask

    卸载包后,相关包和依赖详情会从Pipfile和Pipfile.lock中移除。

    clipboard

    卸载当前环境所有包:

    # 从虚拟环境中移除所有已安装的包,但 Pipfile.lock 文件不受影响
    pipenv uninstall --all

    卸载开发包:

    # 从虚拟环境中卸载所有开发包,并从 Pipfile 文件中移除这些包
    pipenv uninstall –all-dev

    更新依赖包:

    查看所有需要更新的包:

    pipenv update --outdated

    如下图:

    clipboard

    更新指定包:

    pipenv update <包名>

    更新所有包:

    pipenv update

    检查安全漏洞:

    pipenv check  # 检查安全漏洞

    它可能会检查出很多错误,其实如果不影响你使用,你可以直接忽略掉。强迫症患者也可以一个一个问题去解决。

    比如如下问题:

    clipboard

    修改pipenv的镜像源

    可以修改当前目录下Pipfile文件,将[source]下的url属性改成国内的源即可:

    [[source]]
    url = "https://mirrors.aliyun.com/pypi/simple"
    verify_ssl = true
    name = "pypi"

    3、环境部署

    使用pipenv进行多环境部署

    dev与正式环境区分安装。

    当你想要一个包只在开发环境使用,等生产部署的时候,不需要该安装包,你可以这样指定环境安装。

    # 把django安装在开发环境
    pipenv install django --dev

    安装如下图

    clipboard

    安装完成后,查看Pipfile文件:

    会发现,pipenv已经将安装包区分开来了。

    [dev-packages] 里记录的--dev开发环境安装的包

    [package] 里记录的是没有加环境参数,默认就是正式环境的包。

    clipboard

    那么等到你真正迁移到生产环境部署的时候,就只需要这么做:

    pipenv install

    这样默认是只安装[package] 里的安装包的,会自动过滤掉[dev-packages] 里的包。

    让生产环境变得更加纯净,避免有多余的包。

    如下:这是直接pipenv install的,里面是没有django包的

    clipboard

    如果你要迁移到开发环境,只需要这么做:

    pipenv install --dev

    它就会把[dev-packages] 里的包也一起安装上了。

    如下:

    这是使用了--dev参数的,看到已经把djiango安装上了。

    clipboard

    4、Pipfile.lock文件

    Pipfile.lock 利用了pip中一些新的安全改进。默认情况下,Pipfile.lock 包含每个下载的包的 sha256 哈希值。这可以使pip能够保证从不信任的PyPI源安装包时或者在不稳定的网络环境下安装包时都能保证包的正确性与完整性。我们强烈建议通过将项目从开发环境提升到生产环境来进行部署。您可以使用 pipenv lock 编译开发环境上的依赖项,并将编译后的 Pipfile.lock 文件部署到您所有的生产环境,以便进行可重现的构建。

    (使用Pipfile.lock可以锁定之前的安装包,确保迁移重新部署后,能够重现跟之前一样的环境。)

    Pipfile和Pipfile.lock不一致

    因为使用pipenv install的时候,加上–ignore-lock参数,可以忽略 Pipfile.lock 文件而直接安装 Pipfile 中的包。此外,不会更新 Pipfile.lock 文件。

    当pipenv install安装一些比较大的包,比如TensorFlow等科学包,在安装完包,正在解析包依赖的时候,可能会花费很长时间,可能就会ctrl+C停止掉了,此时包已经安装完成,Pipfile已经写入完成,但是没有解析完依赖,所以Pipfile.lock没有写入完成。

    这两种情况都会导致Pipfile和Pipfile.lock不一致的情况,会对应不上。

    此时,可以使用Pipenv lock重新生成Pipfile.lock文件。

    pipenv lock

    如果通过 pipenv 命令安装和卸载 package,安装或卸载完成后还会更新 Pipfile.lock 文件,有时候会卡在这个步骤。通常可以 ctrl+c 强制推出,删除 Pipfile.lock, 然后

    # 重新生成Pipfile.lock文件
    pipenv lock

    默认情况下,使用pipenv install,它会重新解析Pipfile里安装包的依赖性,并将依赖关系更新到Pipfile.lock中。如果你不想要重新解析Pipfile里安装包,只想安装Pipfile.lock文件中现存的依赖包,可以精确的指定只使用Pipfile.lock文件。

    pipenv sync

    可以使用 sync 命令精确安装 Pipfile.lock 文件中指定的包:

    pipenv sync 

    注意:pipenv install --ignore-pipfile 和 pipenv sync 命令很相似,但是pipenv sync 命令永远不会尝试重新锁定依赖项,因为它被认为是一个原子操作。默认情况下,除非使用了 –deploy 标志,否则 pipenv install 会尝试重新锁定依赖项。

    pipenv install --deploy

    可以使用 –deploy 标志强制Pipfile.lock 文件是最新的。

    上述命令将在Pipfile.lock 文件不是最新的时候导致构建失败,而不是生成一个新的。

    5、兼容requirements.txt

    之前我们的pip工具可以从requierments.txt文件中导入依赖包。

    在pipenv,用下面的命令就可以将Pipfile和Pipfile.lock文件里面的包导出为requirements.txt文件。

    # 将Pipfile里的全部包导出到requirements.txt
    pipenv lock -r > requirements.txt

    内容如下:

    clipboard

    可以选择只导出开发环境的包:

    # 只导出开发环境的包
    pipenv lock -r --dev-only > requirements.txt

    如下图:

    clipboard

    导出开发环境+ 默认的环境的包:

    # dev环境和default环境的包都会导出
    pipenv lock -r --dev > requirements.txt

    如下图:

    clipboard

    也可以使用底层pip的命令导出:

    pipenv run pip freeze > requirements.txt

    如下图:

    clipboard

    导入requirements.txt

    导出为requirements.txt后,可以通过pip导入,也可以通过pipenv导入。

    # 通过pip导入
    pip install -r requirements.txt
    # 通过pipenv导入
    pipenv install -r requirements.txt

    6、虚拟环境中运行命令:

    启动shell运行

    正常来说,如果想要让命令运行在虚拟环境,需要启动一个虚拟环境的shell,否则命令还是在系统环境下运行的,如下:

    pipenv shell

    如下图:

    clipboard

    使用run运行:

    如果不想启动shell,而是直接在虚拟环境中执行命令,可以使用run:

    # pipenv run <命令>
    pipenv run python --version

    如下图:

    clipboard

    部署项目的时候,你也可以不进入虚拟环境的方式运行项目:

    pipenv run python xxx.py

    7、环境变量:(.env)

    自动加载.env文件 (利器)

    .env文件可以设置一些环境变量,在程序开发的时候模拟环境变量。

    如果项目目录下包含一个 .env 文件,它会被 pipenv shell 和 pipenv run 命令自动加载:

    # 如下,设置一个变量HELLO,以及配置文件路径的变量
    [root@ops-130 myproj10]# cat .env 
    HELLO=WORLD
    CONFIG_PATH=${HOME}/.config/foo
    
    
    # 测试环境变量
    # 使用pipenv run的时候,会自动加载该环境变量。
    [root@ops-130 myproj10]# pipenv run python
    Loading .env environment variables...
    Python 3.9.9 (main, Dec 31 2021, 15:34:46) 
    [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os
    >>> os.environ['HELLO']
    'WORLD'
    >>> os.environ['CONFIG_PATH']
    '/root/.config/foo'
    >>> 

    这类似于php的lavel框架的.env文件。

    这对于将生产凭证排除在代码库之外非常有用。我们不建议将 .env 文件提交到源代码控制中!

    如果你的 .env 文件位于不同的路径下或者有其他名称,你可以设置一个PIPENV_DOTENV_LOCATION 环境变量:

    PIPENV_DOTENV_LOCATION=/path/to/.env pipenv shell

    要禁止pipenv加载 .env 文件,可以设置 PIPENV_DONT_LOAD_ENV 环境变量:

    PIPENV_DONT_LOAD_ENV=1 pipenv shell

    Pipfile引用环境变量:

    在Pipfile中也可以引用环境变量的值,格式为${MY_ENVAR}或$MY_ENVAR,在Windows系统中还支持%MY_ENVAR%。

    [[source]]
    url = "https://${PYPI_USERNAME}:${PYPI_PASSWORD}@my_private_repo.example.com/simple"
    verify_ssl = true
    name = "pypi"
    
    [packages]
    flask = "*"
    jieba = "*"
    
    [dev-packages]
    django = "*"
    
    [requires]
    python_version = "3.9"

    这里的变量为:${PYPI_USERNAME}:${PYPI_PASSWORD}

    使用前提是,系统中要已经设置了相关的变量。

    当然你可以结合.env文件,将相关变量设置在.env里。


    从setup.py安装依赖包

    很多依赖库都包含setup.py文件,里面也包含了对应包的子依赖信息,这个文件跟Pipfile.lock有点相似,pipenv也提供了堆setup.py的支持。

    pipenv也可以从setup.py安装:

    pipenv install -e .

    更多pipenv的用法,请参考官网:https://pipenv.pypa.io/en/latest/

    8、优缺点分析:

    1、pipenv集成了pip,virtualenv两者的功能,且完善了两者的一些缺陷。

    2、支持Python2 和 Python3,在各个平台的命令都是一样的。

    3、类似npm,容易迁移,便于项目内部协同工作

    4、各个地方使用了哈希校验,无论安装还是卸载包都十分安全,且会自动公开安全漏洞。

    5、通过加载.env文件简化开发工作流程。

    6、Bug 很多,确实比较年轻,安装的流程有些让人困惑,不像 pip 这么直接好理解


    参考引用:

    https://blog.csdn.net/swinfans/article/details/89305301

    https://pipenv.pypa.io/en/latest/

  • 相关阅读:
    怎么判断是从微信浏览器打开还是手机自带的浏览器(其他浏览器)打开?
    h5移动端页面强制横屏
    苹果的正常显示,安卓的不知道写了什么白屏了
    截取地址栏的最后一个参数
    检测手机号码的正则表达式
    js判断是不是在微信浏览器打开?
    LArea插件选中城市,确定之后又很难再次选择城市?
    display: inline-block 布局
    调试
    时间
  • 原文地址:https://www.cnblogs.com/doublexi/p/15791048.html
Copyright © 2020-2023  润新知