以前我一直在用 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
文件,打开项目后自动加载对应的环境。