Pipenv 使用及 Pyinstaller 文件瘦身记录

前言

我通常用 Pyinstaller 将 PixivBiu 的 Python 代码打包成可执行文件,但打包后的体积很令人在意。

Pyinstaller 打包时会把本地环境的包饱和式塞进去,所以如果安装过的 Python 包比较多,那体积可能会很奇怪得偏大。因此,解决办法就是在纯净的虚拟环境中打包,这样就可以尽可能缩小体积了。个人认为这是一个简单但效果很明显的改进方法。

这里就记录一下 Pipenv 的简单使用及以此来缩小文件体积。

Pipenv

Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world. Windows is a first-class citizen, in our world.

It automatically creates and manages a virtualenv for your projects, as well as adds/removes packages from your Pipfile as you install/uninstall packages. It also generates the ever-important Pipfile.lock , which is used to produce deterministic builds.

Pyinstaller

PyInstaller freezes (packages) Python applications into stand-alone executables, under Windows, GNU/Linux, Mac OS X, FreeBSD, Solaris and AIX.

Pipenv

安装

官方文档有说明各种安装方法,这里就简单列举一个不负责任的方法吧。

~ pip install pipenv

创建虚拟环境

  • 如果是一个新的项目,我更偏向通过指定 Python 版本的方式来创建虚拟环境。
~ cd <project_path>
~ pipenv --two  # 使用系统中的 Python2 创建环境
~ pipenv --three  # 使用系统中的 Python3 创建环境
~ pipenv --python x.x  # 使用指定版本的 Python 创建环境

但需要注意的是,Pipenv 并不会安装新的 Python。也就是说,虚拟环境中的 Python 版本只能是已经安装过的了(并且存在于系统的环境变量中)。

如果想要方便管理多个版本的 Python,或是在项目中使用指定的版本,可以使用 Pyenv。

并且,此命令并不能用来切换一个环境的 Python 版本,每次执行都等于创建一个新的虚拟环境。

  • 当然,你也可以通过安装包的形式来快速创建。推荐在存在环境配置文件的情况下使用此方法。
~ pipenv install # 仅安装默认包,不包含开发所需的
~ pipenv --dev # 安装默认以及开发所需的包
~ pipenv --dev-only # 仅安装开发所需的包

此时的创建逻辑是:

  1. 如果目录下没有 Pipfile 和 Pipfile.lock 文件,则默认创建一个新的虚拟环境
  2. 如果有,则使用已有的 Pipfile 和 Pipfile.lock 文件配置创建一个虚拟环境
  3. Python 以及包版本会跟随上述配置文件中的
关于环境文件

Pipenv 并没有安装新的 Python 版本,只是链接。各个环境的包文件都集中放置在一个文件夹中,很是整齐。

使用

Usage: pipenv [OPTIONS] COMMAND [ARGS]...

Options:
  --where                         Output project home information.
  --venv                          Output virtualenv information.
  --py                            Output Python interpreter information.
  --envs                          Output Environment Variable options.
  --rm                            Remove the virtualenv.
  --bare                          Minimal output.
  --completion                    Output completion (to be executed by the
                                  shell).

  --man                           Display manpage.
  --support                       Output diagnostic information for use in
                                  GitHub issues.

  --site-packages / --no-site-packages
                                  Enable site-packages for the virtualenv.
                                  [env var: PIPENV_SITE_PACKAGES]

  --python TEXT                   Specify which version of Python virtualenv
                                  should use.

  --three / --two                 Use Python 3/2 when creating virtualenv.
  --clear                         Clears caches (pipenv, pip, and pip-tools).
                                  [env var: PIPENV_CLEAR]

  -v, --verbose                   Verbose mode.
  --pypi-mirror TEXT              Specify a PyPI mirror.
  --version                       Show the version and exit.
  -h, --help                      Show this message and exit.

Usage Examples:
   Create a new project using Python 3.7, specifically:
   $ pipenv --python 3.7

   Remove project virtualenv (inferred from current directory):
   $ pipenv --rm

   Install all dependencies for a project (including dev):
   $ pipenv install --dev

   Create a lockfile containing pre-releases:
   $ pipenv lock --pre

   Show a graph of your installed dependencies:
   $ pipenv graph

   Check your installed dependencies for security vulnerabilities:
   $ pipenv check

   Install a local setup.py into your virtual environment/Pipfile:
   $ pipenv install -e .

   Use a lower-level pip command:
   $ pipenv run pip freeze

Commands:
  check      Checks for PyUp Safety security vulnerabilities and against PEP
             508 markers provided in Pipfile.

  clean      Uninstalls all packages not specified in Pipfile.lock.
  graph      Displays currently-installed dependency graph information.
  install    Installs provided packages and adds them to Pipfile, or (if no
             packages are given), installs all packages from Pipfile.

  lock       Generates Pipfile.lock.
  open       View a given module in your editor.
  run        Spawns a command installed into the virtualenv.
  shell      Spawns a shell within the virtualenv.
  sync       Installs all packages specified in Pipfile.lock.
  uninstall  Uninstalls a provided package and removes it from Pipfile.
  update     Runs lock, then sync.
常用命令记录
~ pipenv shell # 激活虚拟环境
~ pipenv run <command>
# ---
~ pipenv --where  # 显示当前项目目录
~ pipenv --venv  # 显示虚拟环境文件目录
~ pipenv --py  # 显示虚拟环境 Python 目录
# ---
~ pipenv install xxx  # 安装 xxx 包并写入配置文件
~ pipenv install xxx==1.0  # 安装指定版本的 xxx 包并写入配置文件
~ pipenv install --dev xxx # 安装开发所需的 xxx 包并写入配置文件
# ---
~ pipenv graph # 查看当前环境下安装的包及依赖关系
~ pipenv check
# ---
~ pipenv update --outdated  # 检查需要更新的包
~ pipenv update  # 更新所有包
~ pipenv update xxx  # 更新指定的包
# ---
~ pipenv uninstall xxx  # 卸载 xxx 包并从配置文件中移除
~ pipenv uninstall --all  # 卸载全部包并从配置文件中移除
~ pipenv uninstall --all-dev  # 卸载全部开发所需的包并从配置文件中移除
# ---
~ pipenv --rm # 删除虚拟环境以及文件,但不会删除配置文件
# ---
~ pipenv install -r requirements.txt

虽然传统的 pip install 方式仍可以安装包,但此方法并不会将其写入 Pipfile 以及 Pipfile.lock 文件。因此不是很推荐这种方法安装。

瘦身

在创建完虚拟环境后,仅安装项目所需的包。最后安装 Pyinstaller,开始打包即可。

注意

以下两种代码在打包时并没有体积差别。

import numpy as np

a = np.arange(10).reshape(2, 5)

print(a)
from numpy import arange, reshape

a = arange(10).reshape(2, 5)

print(a)

后言

如果只是在 Pyinstaller 打包瘦身的时候用虚拟环境,那就太大材小用了。

之前写 Python 小脚本的时候习惯直接 pip install 全局安装各种包。虽然问题不大,但有时候更新的时候会各种依赖版本报错。

虚拟环境很好地解决了这一点,还方便代码的分发和管理。而且,一个项目搭配一个干净的环境,想想就有点舒服。((

参考

tag(s): 笔记
show comments · back · home
Edit with markdown