百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

使用 pipx 安装并执行 Python 应用程序 (1)

liuian 2025-03-02 18:02 14 浏览

引言

将Python编写的桌面和命令行程序发布到PyPI是一个简单直接的分发方式,PyPI上存放着成千上万的第三方程序包。这些程序包里很多都带有可以直接运行的脚本,但要使用它们,你得对Python的生态圈有一定的了解。有了pipx这个工具,你可以在不影响全局Python解释器的情况下,安全地安装和运行这些应用程序。

通过本教程[1],你将掌握以下技能:

  • 把Python包索引(PyPI)打造成一个应用商店
  • 不通过Python直接调用就能运行已安装的应用程序
  • 防止不同应用间的依赖性冲突
  • 在临时环境中尝试试用应用程序
  • 管理已安装的应用及其运行环境

为了更好地利用本教程,你需要对命令行操作有一定的熟悉度。特别是,掌握如何在项目中管理Python版本、创建虚拟环境和安装第三方模块,这些技能将对你大有裨益。

管理应用

在本节中,你将通过 pipx 执行多项应用管理任务。安装了 Python 应用后,你可能想要列出这些应用、升级或降级它们的版本,以及卸载不再需要的应用。这些操作与使用传统 pip 管理 Python 包的方式相似。

列出已安装的应用 你无需记住每个已安装 Python 包的具体入口点。任何时候,你都可以通过在终端输入 pipx list 来列出所有已安装的应用及其命令。

$ pipx list
venvs are in /home/user/.local/share/pipx/venvs
apps are exposed on your $PATH at /home/user/.local/bin
manual pages are exposed at /home/user/.local/share/man
   package ipython 8.22.1, installed using Python 3.12.2
    - ipython
    - ipython3
    - man1/ipython.1
   package mypy 1.8.0, installed using Python 3.12.2
    - dmypy
    - mypy
    - mypyc
    - stubgen
    - stubtest
   package pandas 2.2.1, installed using Python 3.12.2
    - f2py
   package poetry 1.8.0, installed using Python 3.12.2
    - poetry
   package ruff 0.2.2, installed using Python 3.12.2
    - ruff

上述命令的输出显示了 pipx 管理的虚拟环境的位置,一个包含指向可执行文件的符号链接的文件夹,以及一个包含一些包提供的手册页作为文档的文件夹。

输出的其他部分包括了已安装的包、它们的版本以及这些包关联的虚拟环境中使用的 Python 解释器。此外,每个包还列出了你可以在终端中调用的命令。

如果你只想显示包名和版本号,可以使用 --short 选项:

$ pipx list --short
ipython 8.22.1
mypy 1.8.0
pandas 2.2.1
poetry 1.8.0
ruff 0.2.2

每个软件包都配有一个专属的虚拟环境,以便单独使用。如果你想了解底层虚拟环境的更多细节,包括解析后的绝对路径信息,可以使用 --json 参数:

$ pipx list --json
{
    "pipx_spec_version": "0.1",
    "venvs": {
        "ipython": {…},
        "mypy": {…},
        "pandas": {…},
        "poetry": {…},
        "ruff": {
            "metadata": {
                "injected_packages": {},
                "main_package": {
                    "app_paths": […],
                    ?
                    "package_version": "0.2.2",
                    "pip_args": [],
                    "suffix": ""
                },
                "pipx_metadata_version": "0.3",
                "python_version": "Python 3.12.2",
                "venv_args": []
            }
        }
    }
}

正如其名所示,这个命令会以 JSON 格式返回结果,非常适合用于自动化任务以及将 pipx 与其他工具集成到你的工作流程中。由于 JSON 具有机器可读的特性,你可以通过编程方式获取包的版本、位置和依赖关系等详细信息。

一旦你了解了哪些应用被安装在系统中,你就可以执行它们的命令或调整它们的虚拟环境。

升级

如果你想使用常规的 pip 工具将现有的 Python 包升级到最新版本,你会运行带有 --upgrade 标志的 pip install 命令。而在使用 pipx 时,你可以通过 upgrade 子命令来完成相同的升级操作:

$ pipx upgrade ruff
upgraded package ruff from 0.0.292 to 0.2.2 (location: /.../venvs/ruff)

$ pipx upgrade ruff
ruff is already at latest version 0.2.2 (location: /.../venvs/ruff)

这个操作会定位到相应的虚拟环境,并利用其中的 Python 解释器执行 python -m pip install --upgrade ruff 命令。这样做很便捷,因为你无需自己寻找并手动激活正确的虚拟环境。

当你通过 pipx 安装了许多不同虚拟环境中的包时,这个过程也相对简单。如果手动逐个升级这些包会是一项庞大的工作。幸运的是,你可以通过 upgrade-all 子命令一次性将所有包升级到它们的最新版本:

$ pipx upgrade-all
upgraded package ruff from 0.0.292 to 0.2.2 (location: /.../venvs/ruff)
upgraded package poetry from 1.2.2 to 1.8.0 (location: /.../venvs/poetry)
upgraded package mypy from 1.6.1 to 1.8.0 (location: /.../venvs/mypy)
upgraded package ipython from 7.34.0 to 8.22.1 (location: /.../venvs/ipython)
upgraded package pandas from 2.1.1 to 2.2.1 (location: /.../venvs/pandas)

执行这个命令可以确保你安装的所有包都是最新版本。

如果你不想总是使用最新版本,而只是想将某个包升级到特定版本,或者你想要降级某个包而不是升级,你将在下一节中找到实现这两种操作的方法。

降级应用到特定版本 pipx 没有提供直接降级已安装包的命令。当你尝试安装一个你之前已经安装过的 Python 包的特定旧版本时,pipx 会阻止这一操作。同时,它会告诉你正确的处理方法:

$ pipx install ruff==0.0.292
'ruff' already seems to be installed. Not modifying existing installation
? in '/home/user/.local/share/pipx/venvs/ruff'.
? Pass '--force' to force installation.

在 pip 中,你可以通过指定需求说明符来降级一个包,但在 pipx 中不能这样做。相反,你需要使用 --force 标志来指示工具可以修改现有的虚拟环境:

$ pipx install --force ruff==0.0.292
Installing to existing venv 'ruff'
  installed package ruff 0.0.292, installed using Python 3.12.2
  These apps are now globally available
    - ruff
done! ?  ?

pipx 工具在内部将 --force 参数转换为 --force-reinstall 并传递给 pip。这意味着 pip 会重新安装包,即使它们已经在目标版本中。

最终,如果没有任何包的版本能满足你的要求,可能就需要完全卸载该包并寻找其他替代品了。

卸载虚拟环境

要一并移除 Python 包及其由 pipx 管理的虚拟环境,你可以使用命名直观的 uninstall 子命令:

$ pipx uninstall ruff
uninstalled ruff! ?  ?

这个操作还会移除与这些包相关的手册页和 shell 中的符号链接,这意味着你将无法再使用它们。

如果你想一次性卸载所有包,pipx 也提供了相应的解决方案:

$ pipx uninstall-all
uninstalled poetry! ?  ?
uninstalled mypy! ?  ?
uninstalled ipython! ?  ?
uninstalled pandas! ?  ?

$ pipx list
nothing has been installed with pipx 

现在,你可以重新开始,像一张白纸一样!但如果你经常使用 pipx 安装的许多工具,请小心使用这个命令,因为重新安装它们可能需要一些时间。

虚拟环境

在接下来的几个部分中,你将学习如何修改 pipx 管理的虚拟环境。在这个过程中,你将看到一些在你的开发工作流程中可能遇到的实用案例。

依赖项

使用 pipx 而不是 pip 的一个主要好处是,pipx 为你管理虚拟环境,确保安装的包能够正确隔离。一方面,pipx 提供了方便和安全保障,但另一方面,它似乎阻止了你对这些虚拟环境的调整。有时,你可能需要对这些环境有一定的控制。

例如,如果你按照官方文档推荐的方式使用 pipx 安装了 Poetry,那么你可能在稍后需要安装一个可选插件,比如 poetry-plugin-export。在这种情况下,可以使用 pipx inject 命令:

$ pipx inject poetry poetry-plugin-export poetry-plugin-bundle
  injected package poetry-plugin-export into venv poetry
done! ?  ?
  injected package poetry-plugin-bundle into venv poetry
done! ?  ?

inject 子命令需要你提供之前安装过的原始包名,比如 poetry,然后是你想添加的一个或多个额外依赖项的列表。这个包名用于识别 pipx 为你管理的相应虚拟环境。

为了验证这些新依赖项是否已正确添加到虚拟环境,你可以使用 pipx runpip 命令。这个命令允许你在应用的虚拟环境中执行任意的 pip 命令:

$ pipx runpip poetry list | grep poetry
poetry               1.8.0
poetry-core          1.9.0
poetry-plugin-bundle 1.3.0
poetry-plugin-export 1.6.0

这里,你运行 pip list 命令在 Poetry 的虚拟环境中,以获得所有已安装依赖项的完整清单。接着,你将该命令的输出结果进行筛选,仅展示那些名称中包含“poetry”这个词的包。

你也可以利用 runpip 命令来升级或降级 pipx 管理的虚拟环境中的依赖项,并且通过将依赖项版本锁定到一个需求文件中来固定它们的版本号:

$ pipx runpip poetry install poetry-plugin-export==1.3.1
$ pipx runpip poetry install poetry-plugin-export --upgrade
$ pipx runpip poetry freeze > requirements.txt

尽管技术上你可以使用 runpip 命令来移除受管虚拟环境中的依赖项,但使用 pipx 提供的更直接的 uninject 子命令会是一个更好的选择:

$ pipx uninject poetry poetry-plugin-export
Uninjected package poetry-plugin-export
? and its dependencies from venv poetry ?  ?

如果你使用 pip 手动卸载某个依赖项,可能会遗留下一些间接或传递性的依赖。而 pipx uninject 会自动处理这些依赖,确保不会留下任何未使用的依赖项。

使用 pipx inject 的另一个场景是,当你需要在基于 Python 3.12 或更高版本的虚拟环境中执行 mypyc 命令时。Mypy 的 C 扩展模块编译器需要 setuptools,但从 Python 3.12 版本开始,setuptools 不再包含在 Python 中。截至本文撰写时,mypy 并未将 setuptools 列为依赖项,因为它原本预期 setuptools 会随 Python 一起提供。因此,直接在终端运行 mypyc 会因为缺少 setuptools 而报错:

$ mypyc
Traceback (most recent call last):
  ...
ModuleNotFoundError: No module named 'setuptools'

pipx Inject 命令可以解决这个问题,让您将缺少的依赖项安装到正确的虚拟环境中:

$ pipx inject mypy setuptools
  injected package setuptools into venv mypy
done! ?  ?

现在有了 setuptools,您可以运行 mypyc 来编译基于类型注释的 Python 代码的 C 扩展模块:

$ cat adder.py
def add(x: float, y: float) -> float:
    return x + y

$ mypyc adder.py
running build_ext
building 'adder' extension
creating build/temp.linux-x86_64-cpython-312
creating build/temp.linux-x86_64-cpython-312/build
gcc -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -fPIC ...
creating build/lib.linux-x86_64-cpython-312
gcc -shared -L/home/user/.pyenv/versions/3.12.2/lib -Wl,-rpath,/home/...
copying build/.../adder.cpython-312-x86_64-linux-gnu.so ->

当您将生成的动态链接库导入 Python REPL 会话并调用 add() 时,该函数似乎被编译到您平台的本机代码中:

>>> import adder

>>> adder


>>> adder.add


>>> adder.add(3.14, 2.72)
5.86

作为另一种选择,你不必向受管的虚拟环境注入缺失的依赖项,而是可以将 Python 版本降级到自带 setuptools 的版本。这是你接下来将执行的操作。

指定版本

通常,pipx 会使用你安装 pipx 时所用的 Python 解释器中的 venv 模块来创建新的虚拟环境。具体来说,如果你是通过 python -m pip install pipx 安装的,那么 pipx 会使用你当前激活环境的解释器。如果你使用的是操作系统的包管理器,那么它可能会使用全局 Python 或另一个可能已过时的独立解释器。

你可以在两种情况下指定使用不同的默认 Python 解释器:

  1. 在用 pipx 安装某个 Python 包之前
  2. 在已经安装了一个包之后作为补救措施

第一种情况更为简单,因此你会首先考虑它。如果你想要了解如何在已存在的虚拟环境中更改 Python 版本,请查看下一节内容,那里会介绍如何使用 reinstall 子命令。

pipx run 和 pipx install 命令都支持 PIPX_DEFAULT_PYTHON 环境变量,你可以通过它来指定默认的 Python 解释器:

$ export PIPX_DEFAULT_PYTHON=/path/to/python-3.13.0a4/bin/python3
$ pipx run ipython
Python 3.13.0a4 (tags/v3.13.0a4:9d34f60783, Feb 26 2024, 13:03:08) [GCC 13.2.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.22.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

在这里,你通过环境变量指定了一个 Python alpha 版本的自定义构建路径,这个版本是你从 GitHub 克隆并自行编译的。接着,利用 pipx,你在基于这个 alpha 版本的临时虚拟环境中启动了一个 IPython 会话,IPython 启动时的消息确认你正在运行的是 Python 3.13.0a4 版本。

此外,pipx run 和 pipx install 命令还提供了一个可选的 --python 参数,允许你为特定的虚拟环境指定 Python 解释器。这个参数可以接受以下几种值之一:

  • 文件路径:你文件系统中 python 可执行文件的绝对路径
  • 可执行文件:如果该名称在你的 PATH 环境变量中,则为可执行文件的名称
  • 版本:Windows 上 Python Launcher 能够识别的 Python 版本

如果你已经配置了 pyenv 或 pyenv-win,你可以在系统级解释器旁边安装一个旧版本的 Python,以及其他你可能已经安装或自行编译的解释器。然后,你应该找到 pyenv 存储 Python 版本的目录中的相应 python 可执行文件。或者,你可以临时将新安装的 Python 设置到你的 shell 中,并查找其可执行文件的路径:

$ pyenv install 3.11.8
Downloading Python-3.11.8.tar.xz...
-> https://www.python.org/ftp/python/3.11.8/Python-3.11.8.tar.xz
Installing Python-3.11.8...
Installed Python-3.11.8 to /home/user/.pyenv/versions/3.11.8
$ pyenv shell 3.11.8
$ pyenv which python
/home/user/.pyenv/versions/3.11.8/bin/python

一旦您知道首选 Python 解释器的完整路径,您可以在安装 mypy 或其他包时将其传递给 pipx:

$ pipx install --python=/home/user/.pyenv/versions/3.11.8/bin/python mypy
  installed package mypy 1.8.0, installed using Python 3.11.8
  These apps are now globally available
    - dmypy
    - mypy
    - mypyc
    - stubgen
    - stubtest
done! ?  ?

命令执行结果显示 pipx 已根据指定的 Python 解释器创建了虚拟环境。你可以用 pipx list 命令再次列出已安装的包,以进行再次确认。

奇怪的是,即便你现在已经切换到了一个较旧的 Python 版本,理论上应该在新环境中包含 setuptools,但尝试运行 mypyc 时你还是会遇到之前的错误:

$ pipx runpip mypy list
Package           Version
----------------- -------
mypy              1.8.0
mypy-extensions   1.0.0
pip               24.0
typing_extensions 4.9.0

如你所见,在受管理的虚拟环境中没有 setuptools。原来,pipx 创建的是只包含安装包及其依赖的最小化环境。这是因为 pipx 在运行 venv 模块时使用了 --without-pip 开关,这样就跳过了 pip 和 setuptools 这类包的安装。因此,你需要手动安装 setuptools。

对于你之前用 pipx 安装的应用,你将了解到如何控制它们各自虚拟环境中的 Python 版本。

更改Python 版本

如果你只想更改已安装应用的 Python 版本而不影响其他设置,你可以使用 pipx reinstall 命令。在没有额外参数的情况下执行该命令,它会移除应用及其独立的虚拟环境,并按照你最初设置的选项重新安装。

话虽如此,pipx reinstall 命令也支持 --python 参数,允许你使用任何你喜欢的 Python 版本重新创建已安装应用的虚拟环境:

$ pipx reinstall --python=/path/to/python-3.13.0a4/bin/python3 ipython
uninstalled ipython! ?  ?
  installed package ipython 8.22.1, installed using Python 3.13.0a4
  These apps are now globally available
    - ipython
    - ipython3
  These manual pages are now globally available
    - man1/ipython.1
done! ?  ?

你现在可以在任何地方通过终端启动 ipython,它将运行在你用 pipx 指定的 Python 3.13 alpha 4 版本上。

如果你升级了主要的 Python 解释器,并希望使用 --python 选项切换到一个更新的版本,那么用 pipx 重新安装 Python 应用会非常有用。鉴于在虚拟环境中升级 Python 版本是一个常见操作,pipx 提供了另一个便捷的子命令 reinstall-all,它能够一次性完成所有虚拟环境中的升级或降级操作:

$ pipx reinstall-all --python=python3.12
uninstalled ipython! ?  ?
  installed package ipython 8.22.1, installed using Python 3.12.2
  These apps are now globally available
    - ipython
    - ipython3
  These manual pages are now globally available
    - man1/ipython.1
done! ?  ?
uninstalled pandas! ?  ?
  installed package pandas 2.2.1, installed using Python 3.12.2
  These apps are now globally available
    - f2py
done! ?  ?
?

请注意,这个操作会重新安装所有包,哪怕其中一些包已经在使用你期望的 Python 版本。为了避免这种情况,或者保留一些应用的原样,你可以通过 --skip 参数选择性地列出某些包以排除它们:

$ pipx reinstall-all --python=python3.12 --skip poetry pandas mypy

确保在继续之前,你 PATH 环境变量中的某个路径下能找到对应的 Python 可执行文件。执行完这个命令后,pipx 会使用你指定的 Python 版本重新安装所有未被明确排除的 Python 应用程序。

总结

现在,你对 pipx 在日常 Python 编程中解决的问题有了很好的理解。你知道了如何安装和配置 pipx,以及如何在不进行安装的情况下使用它。有了这些知识,你可以安全地在隔离的虚拟环境中运行命令行 Python 应用,避免依赖冲突。

在本教程中,你学习了如何:

  • 将 Python 包索引(PyPI)转变为应用市场
  • 无需显式调用 Python 即可运行已安装的应用
  • 避免不同应用间的依赖冲突
  • 在临时位置尝试临时应用
  • 管理已安装应用及其环境

将 pipx 整合到你的编程工具箱中,无疑会提升你使用 Python 时的工作效率。

[1]Source: https://realpython.com/python-pipx/

相关推荐

总结下SpringData JPA 的常用语法

SpringDataJPA常用有两种写法,一个是用Jpa自带方法进行CRUD,适合简单查询场景、例如查询全部数据、根据某个字段查询,根据某字段排序等等。另一种是使用注解方式,@Query、@Modi...

解决JPA在多线程中事务无法生效的问题

在使用SpringBoot2.x和JPA的过程中,如果在多线程环境下发现查询方法(如@Query或findAll)以及事务(如@Transactional)无法生效,通常是由于S...

PostgreSQL系列(一):数据类型和基本类型转换

自从厂子里出来后,数据库的主力就从Oracle变成MySQL了。有一说一哈,贵确实是有贵的道理,不是开源能比的。后面的工作里面基本上就是主MySQL,辅MongoDB、ES等NoSQL。最近想写一点跟...

基于MCP实现text2sql

目的:基于MCP实现text2sql能力参考:https://blog.csdn.net/hacker_Lees/article/details/146426392服务端#选用开源的MySQLMCP...

ORACLE 错误代码及解决办法

ORA-00001:违反唯一约束条件(.)错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。ORA-00017:请求会话以设置跟踪事件ORA-00018:超出最大会话数ORA-00...

从 SQLite 到 DuckDB:查询快 5 倍,存储减少 80%

作者丨Trace译者丨明知山策划丨李冬梅Trace从一开始就使用SQLite将所有数据存储在用户设备上。这是一个非常不错的选择——SQLite高度可靠,并且多种编程语言都提供了广泛支持...

010:通过 MCP PostgreSQL 安全访问数据

项目简介提供对PostgreSQL数据库的只读访问功能。该服务器允许大型语言模型(LLMs)检查数据库的模式结构,并执行只读查询操作。核心功能提供对PostgreSQL数据库的只读访问允许L...

发现了一个好用且免费的SQL数据库工具(DBeaver)

缘起最近Ai不是大火么,想着自己也弄一些开源的框架来捣腾一下。手上用着Mac,但Mac都没有显卡的,对于学习Ai训练模型不方便,所以最近新购入了一台4090的拯救者,打算用来好好学习一下Ai(呸,以上...

微软发布.NET 10首个预览版:JIT编译器再进化、跨平台开发更流畅

IT之家2月26日消息,微软.NET团队昨日(2月25日)发布博文,宣布推出.NET10首个预览版更新,重点改进.NETRuntime、SDK、libraries、C#、AS...

数据库管理工具Navicat Premium最新版发布啦

管理多个数据库要么需要使用多个客户端应用程序,要么找到一个可以容纳你使用的所有数据库的应用程序。其中一个工具是NavicatPremium。它不仅支持大多数主要的数据库管理系统(DBMS),而且它...

50+AI新品齐发,微软Build放大招:拥抱Agent胜算几何?

北京时间5月20日凌晨,如果你打开微软Build2025开发者大会的直播,最先吸引你的可能不是一场原本属于AI和开发者的技术盛会,而是开场不久后的尴尬一幕:一边是几位微软员工在台下大...

揭秘:一条SQL语句的执行过程是怎么样的?

数据库系统能够接受SQL语句,并返回数据查询的结果,或者对数据库中的数据进行修改,可以说几乎每个程序员都使用过它。而MySQL又是目前使用最广泛的数据库。所以,解析一下MySQL编译并执行...

各家sql工具,都闹过哪些乐子?

相信这些sql工具,大家都不陌生吧,它们在业内绝对算得上第一梯队的产品了,但是你知道,他们都闹过什么乐子吗?首先登场的是Navicat,这款强大的数据库管理工具,曾经让一位程序员朋友“火”了一把。Na...

详解PG数据库管理工具--pgadmin工具、安装部署及相关功能

概述今天主要介绍一下PG数据库管理工具--pgadmin,一起来看看吧~一、介绍pgAdmin4是一款为PostgreSQL设计的可靠和全面的数据库设计和管理软件,它允许连接到特定的数据库,创建表和...

Enpass for Mac(跨平台密码管理软件)

还在寻找密码管理软件吗?密码管理软件有很多,但是综合素质相当优秀且完全免费的密码管理软件却并不常见,EnpassMac版是一款免费跨平台密码管理软件,可以通过这款软件高效安全的保护密码文件,而且可以...