使用 pipenv + direnv 来管理 python 的项目依赖环境

以前我一直在用 virtualenv + virtualenvwrapper 插件,其实用的也好好的,就是依赖不能像 node 的 yarn 一样区分开发和生产,而且没有 lock 文件,锁定版本都靠 requirements.txt 文件,略有不便。今天无聊搜了一下 python 的包管理软件,发现了 pipenv。初步看了下介绍 ,这不就是我想要的嘛。遂尝试将以前的一个爬虫项目转为使用 pipenv 管理。

安装 pipenv

安装 pipenv 非常容易,只要用 pip install pipenv 命令安装就好。

基本使用方法

先进入项目目录

cd ~/dev/mh

安装相关依赖

pipenv install Scrapy

这时候注意了,当项目还没有建立 env 的时候,pipenv 会自动的建立一个对应当前项目的 env 环境,并把依赖包安装进去。在我的机器上是在 ~/.virtualenvs 文件夹里面。然后会生成 Pipfile 文件,里面有依赖包的信息,格式是 toml。我注意到里面还有指定 url 可以使用国内的镜像来加速安装。

pipenv install ipython --dev

当加入 --dev 参数时,安装的依赖就会放到 [dev-packages] 下面,在生产环境可以不安装这个里面的包,减小体积。

锁定版本

当安装包所有的依赖包后,执行 pipenv lock 会在 Pipfile.lock 里面记录当前所有依赖的版本,当部署到新机器上的时候执行 pipenv sync 就可以安装对应的依赖了,非常方便。

在新机器上同步环境

# 安装环境,生产环境用这条
pipenv sync 

# 同时安装开发依赖
pipenv sync -d

查看依赖关系

$ pipenv graph
autopep8==1.3.5
  - pycodestyle [required: >=2.3, installed: 2.3.1]
flake8==3.5.0
  - mccabe [required: >=0.6.0,<0.7.0, installed: 0.6.1]
  - pycodestyle [required: >=2.0.0,<2.4.0, installed: 2.3.1]
  - pyflakes [required: >=1.5.0,<1.7.0, installed: 1.6.0]
ipython==6.4.0
  - appnope [required: Any, installed: 0.1.0]
  - backcall [required: Any, installed: 0.1.0]
  - decorator [required: Any, installed: 4.3.0]
  - jedi [required: >=0.10, installed: 0.12.1]
    - parso [required: >=0.3.0, installed: 0.3.0]
  - pexpect [required: Any, installed: 4.6.0]
    - ptyprocess [required: >=0.5, installed: 0.6.0]
  - pickleshare [required: Any, installed: 0.7.4]
  - prompt-toolkit [required: >=1.0.15,<2.0.0, installed: 1.0.15]
    - six [required: >=1.9.0, installed: 1.11.0]
    - wcwidth [required: Any, installed: 0.1.7]
  - pygments [required: Any, installed: 2.2.0]
  - setuptools [required: >=18.5, installed: 39.2.0]
  - simplegeneric [required: >0.8, installed: 0.8.1]
  - traitlets [required: >=4.2, installed: 4.3.2]
    - decorator [required: Any, installed: 4.3.0]
    - ipython-genutils [required: Any, installed: 0.2.0]
    - six [required: Any, installed: 1.11.0]
Pillow==5.2.0
Scrapy==1.5.0
  - cssselect [required: >=0.9, installed: 1.0.3]
  - lxml [required: Any, installed: 4.2.3]
  - parsel [required: >=1.1, installed: 1.4.0]
    - cssselect [required: >=0.9, installed: 1.0.3]
    - lxml [required: >=2.3, installed: 4.2.3]
    - six [required: >=1.5.2, installed: 1.11.0]
    - w3lib [required: >=1.8.0, installed: 1.19.0]
      - six [required: >=1.4.1, installed: 1.11.0]
  - PyDispatcher [required: >=2.0.5, installed: 2.0.5]
  - pyOpenSSL [required: Any, installed: 18.0.0]
    - cryptography [required: >=2.2.1, installed: 2.2.2]
      - asn1crypto [required: >=0.21.0, installed: 0.24.0]
      - cffi [required: >=1.7, installed: 1.11.5]
        - pycparser [required: Any, installed: 2.18]
      - idna [required: >=2.1, installed: 2.7]
      - six [required: >=1.4.1, installed: 1.11.0]
    - six [required: >=1.5.2, installed: 1.11.0]
  - queuelib [required: Any, installed: 1.5.0]
  - service-identity [required: Any, installed: 17.0.0]
    - attrs [required: Any, installed: 18.1.0]
    - pyasn1 [required: Any, installed: 0.4.3]
    - pyasn1-modules [required: Any, installed: 0.2.2]
      - pyasn1 [required: >=0.4.1,<0.5.0, installed: 0.4.3]
    - pyopenssl [required: >=0.12, installed: 18.0.0]
      - cryptography [required: >=2.2.1, installed: 2.2.2]
        - asn1crypto [required: >=0.21.0, installed: 0.24.0]
        - cffi [required: >=1.7, installed: 1.11.5]
          - pycparser [required: Any, installed: 2.18]
        - idna [required: >=2.1, installed: 2.7]
        - six [required: >=1.4.1, installed: 1.11.0]
      - six [required: >=1.5.2, installed: 1.11.0]
  - six [required: >=1.5.2, installed: 1.11.0]
  - Twisted [required: >=13.1.0, installed: 18.4.0]
    - Automat [required: >=0.3.0, installed: 0.7.0]
      - attrs [required: >=16.1.0, installed: 18.1.0]
      - six [required: Any, installed: 1.11.0]
    - constantly [required: >=15.1, installed: 15.1.0]
    - hyperlink [required: >=17.1.1, installed: 18.0.0]
      - idna [required: >=2.5, installed: 2.7]
    - incremental [required: >=16.10.1, installed: 17.5.0]
    - zope.interface [required: >=4.4.2, installed: 4.5.0]
      - setuptools [required: Any, installed: 39.2.0]
  - w3lib [required: >=1.17.0, installed: 1.19.0]
    - six [required: >=1.4.1, installed: 1.11.0]

执行 pipenv graph 命令会像上面那样显示出各个包的依赖关系。

配合 direnv 使用

direnv 工具可以在进入目录时自动切换当前的环境,不需要手动执行 pipenv shell。我用的是mac,使用 brew install direnv 命令安装,其它的系统参考 https://github.com/direnv/direnv。

在 shell 启动时载入 direnv

我用的是 fish ,按照官方的说明 https://github.com/direnv/direnv#fish ,只要在 fish 的启动配置 (一般是在 ~/.config/fish/config.fish,我用了 oh-my-fish ,所以在 ~/.config/omf/init.fish) 里面加入 eval (direnv hook fish) 这条命令就可以了。

在项目目录里面启用

现在已经安装好 direnv 了,到项目的目录里面添加一个 .envrc 文件,内容是 layout_pipenv,保存后再执行 direnv allow。这样就启动了当前目录的自动切换环境功能,只要进入项目目录就会自动执行 pipenv shell

PS: 我发现在 vscode 里面,安装了 python 插件后也能自动识别 .envrc 文件,打开项目后自动加载对应的环境。

vscode

你可能感兴趣的:(使用 pipenv + direnv 来管理 python 的项目依赖环境)