SymPy 依赖指南:硬依赖、可选依赖与开发依赖全解析
【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy
SymPy 是一个用纯 Python 编写的计算机代数系统,其核心代码库对第三方库的依赖非常克制:整个运行只有 mpmath 一个硬依赖,其余均为按需启用的可选依赖。本文以仓库文档 doc/src/contributing/dependencies.md 为主干,结合 sympy/init.py、sympy/external/importtools.py、sympy/external/gmpy.py、sympy/core/backend.py 等源码实现,系统梳理 SymPy 的依赖全景:哪些是必须安装的、哪些能显著提升性能、哪些只服务于特定功能(绘图、解析、SAT、代码生成、统计采样等),以及贡献者在测试、文档、基准测试场景下还需要哪些开发依赖。读完本文,你将能根据使用场景精准决定需要安装哪些包,并理解 SymPy 如何在缺失依赖时优雅降级或跳过测试。
依赖总览与定位
SymPy 的依赖可以划分为三个层次:
| 层次 | 典型包 | 缺失后果 |
|---|---|---|
| 硬依赖 | mpmath | import sympy直接失败 |
| 推荐可选依赖 | gmpy2 | 功能正常,但大整数与多项式运算性能下降 |
| 功能型可选依赖 | matplotlib、lark、pycosat、numpy 等 | 仅对应功能(绘图、解析、SAT 求解、lambdify 后端等)不可用或降级 |
| 开发依赖 | git、pytest、hypothesis、cloudpickle、asv 等 | 影响测试运行、文档构建与基准测试 |
文档特别强调了两点边界:
- 文中列出的是SymPy 依赖的包,而非依赖 SymPy 的包;反向依赖清单可在主站点与依赖图谱中查看,不在本文讨论范围。
- 绝大多数用户与贡献者不需要安装下面提到的任何包(除硬依赖 mpmath),除非他们打算使用或参与开发依赖这些包的功能模块。
仓库根目录的 pyproject.toml 与 requirements-dev.txt 可以交叉印证上述分层:requirements-dev.txt首行即mpmath,随后是mypy、sphinx-lint、pytest、hypothesis、ruff、slotscheck等纯开发/工具链包,而 gmpy2、matplotlib 等运行期可选依赖并未出现在其中——它们由各功能模块在运行时按需检测。
硬依赖:mpmath
SymPy 唯一的硬依赖是mpmath,一个纯 Python 的任意精度算术库。它被用于 SymPy 计算函数浮点数值的一切底层场景,例如evalf(见 sympy/core/evalf.py)。在 sympy/init.py 中,SymPy 在导入阶段就强制校验 mpmath:
import mpmath ... raise ImportError("SymPy now depends on mpmath as an external library. " "See https://docs.sympy.org/latest/install.html#mpmath for more information.")如果导入时报出上述ImportError,说明 mpmath 没有被正确安装。绝大多数安装 SymPy 的方式(如pip install sympy、conda 安装)都会自动带上 mpmath;只有在直接基于 git 仓库开发、并未真正安装 SymPy 的情况下,才需要手动补齐 mpmath。
源码层面,SymPy 将大量对 mpmath 的直接访问集中收敛在 sympy/external/mpmath.py 中,并做了版本兼容处理,例如针对 mpmath < 1.4.0 与 < 1.5 的 API 差异做了分支适配(mpf_log/mpf_ln、repr_dps)。此外该模块还提供conserve_mpmath_dps装饰器与local_workprec上下文管理器,用于在函数调用前后保持/借用 mpmath 的全局精度(mpmath.mp.dps),这说明 SymPy 不仅依赖 mpmath,还深度管理其精度上下文,避免高精度运算相互污染。
推荐可选依赖:gmpy2
gmpy2 是 GMP 多精度库的 Python 封装,提供比 Python 内置int更快的大整数。SymPy 在安装 gmpy2 后自动启用,无需任何额外配置。文档建议所有有条件的用户安装它,以提升整体体验。
从源码 sympy/external/gmpy.py 可以看出其自动探测机制:
_SYMPY_GROUND_TYPES = os.environ.get('SYMPY_GROUND_TYPES', 'auto').lower() def _get_gmpy2(sympy_ground_types): if sympy_ground_types not in ('auto', 'gmpy', 'gmpy2'): return None gmpy = import_module('gmpy2', min_module_version=_GMPY2_MIN_VERSION, module_version_attr='version', module_version_attr_call_args=()) if sympy_ground_types != 'auto' and gmpy is None: warn("gmpy2 library is not installed, switching to 'python' ground types") return gmpy要点如下:
- 环境变量
SYMPY_GROUND_TYPES可取auto、gmpy、gmpy2、python、flint,默认auto;auto模式下优先使用 flint,其次 gmpy2,最后回落到 Python 原生类型。 - gmpy2 版本必须不低于
_GMPY2_MIN_VERSION(源码中限定gmpy2 >= 2.0.0才会被采用),且由于 gmpy2 的version()是函数而非__version__属性,探测时特意传入了module_version_attr='version'、module_version_attr_call_args=()。 - 若明确指定
gmpy/gmpy2却未安装,会输出 "gmpy2 library is not installed, switching to 'python' ground types" 警告并自动降级,而不是崩溃。
gmpy2 之所以只是"推荐"而非硬依赖,是因为它依赖非 Python、且非 BSD 许可证的 GMP 库。它主要加速对整数运算敏感的核心函数,尤其是 sympy/polys(多项式系统)。而 polys 又被积分算法、collect()、factor()等化简算法、矩阵模块以及部分 core 代码广泛使用,因此安装 gmpy2 能间接加速 SymPy 的很多场景。配套的纯 Python 回退实现位于 sympy/external/ntheory.py,该文件开头即注明"提供一些在安装了 gmpy2 时会被替换使用的数论函数的纯 Python 实现",如bit_scan1/bit_scan0等。
交互式使用相关依赖
SymPy 同时面向交互式与库两种使用方式。交互场景下,它可与 IPython、Jupyter Notebook 无缝集成:
- IPython:
init_session()函数与isympy命令在检测到 IPython 时会自动启动它。除 IPython 自身的增强外,这还开启了 matplotlib 交互绘图,且auto_symbols、auto_int_to_Integer等标志仅在 IPython 中生效。另外,运行 sympy/interactive 下的部分测试也需要 IPython 包。 - Jupyter Notebook 与 Qt Console:SymPy 表达式在 Jupyter Notebook 中自动以 MathJax 渲染,在 Qt Console 中(配合 LaTeX)以 LaTeX 渲染。
入口实现位于 sympy/interactive/session.py 与 sympy/interactive/printing.py。
打印相关依赖
preview()函数负责把 SymPy 表达式转换为由 LaTeX 渲染的图片,可保存到文件或调用查看器展示。因此LaTeX 发行版(TeX Live 或 MiKTeX)是preview()工作的前提;不安装 LaTeX 时,预览功能不可用,但不会影响其他打印方式(如 pretty print、str、MathJax 渲染)。
解析(Parsing)相关依赖
sympy/parsing 子模块中部分解析器需要外部依赖,但并非全部:
- Python 解析器
parse_expr、Mathematica 解析器parse_mathematica、Maxima 解析器parse_maxima均不需要任何外部依赖。 - antlr-python-runtime / antlr4-python3-runtime:LaTeX 解析器
parse_latex(见 sympy/parsing/latex)与 Autolev 解析器(见 sympy/parsing/autolev)依赖 ANTLR Python 运行时。特别注意:运行时版本必须与编译解析器时使用的 ANTLR 版本(4.10)一致。conda 包名为antlr-python-runtime,pip 包名为antlr4-python3-runtime。 - lark:可作为
parse_latex的替代后端(不装 ANTLR 时的另一条路径)。 - Clang Python Bindings:C 解析器
sympy.parsing.c.parse_c需要 Clang Python 绑定(conda 包名python-clang,pip 包名clang)。 - lfortran:Fortran 解析器(sympy/parsing/fortran)需要 LFortran。
逻辑(Logic)与 SAT 求解器
satisfiable()内置纯 Python 的 DPLL 可满足性算法,但可选用更快的 C 语言 SAT 求解器后端。注意satisfiable()也被ask()内部使用:
- pycosat:安装后自动使用,也可通过
satisfiable(algorithm='pycosat')强制指定。 - pysat:封装多种 SAT 求解器的库,目前只实现了 Minisat 后端,通过
satisfiable(algorithm='minisat22')调用(注意文档原文为minisat22',实际使用时为字符串'minisat22')。
核心实现位于 sympy/logic/inference.py。
绘图相关依赖
sympy/plotting/plot.py 重度依赖外部绘图库来渲染图形:
- matplotlib:绝大部分绘图功能要求安装 Matplotlib。没有它时,大多数绘图函数会失败或退化为简陋的文本图
textplot(见 sympy/plotting/textplot.py)。 - pyglet:子模块 sympy/plotting/pygletplot 通过 pyglet 实现 2D/3D 交互绘图(该模块源码大量依赖 pyglet 的
Window、App等接口)。
lambdify:数值后端依赖
lambdify是 SymPy 与数值库之间的标准桥梁:把符号表达式转换为可被数值求值的 Python 函数。它天然支持"任何用户以第三个参数传入命名空间字典的库",同时内置了对多个流行数值库的翻译支持:
| 后端 | 启用方式 | 说明 |
|---|---|---|
| NumPy | 默认(已安装时) | 未安装时回退到标准库math(主要为向后兼容) |
| SciPy | 自动 | 求解 NumPy 未覆盖的部分特殊函数 |
| CuPy | lambdify(modules='cupy') | CUDA GPU 上的 NumPy 兼容接口 |
| JAX | lambdify(modules='jax') | 基于 XLA,可在 GPU/TPU 上编译运行 |
| TensorFlow | lambdify(modules='tensorflow') | 机器学习生态 |
| NumExpr | lambdify(modules='numexpr') | NumPy 的快速数值表达式求值器 |
| mpmath | 内置支持 | 输出纯 mpmath 函数(mpmath 本就是硬依赖) |
源码 sympy/utilities/lambdify.py 中可看到其后端探测逻辑:先检查numexpr是否出现在 modules 列表且列表长度大于 1,随后依次探测cupy、jax、numexpr、tensorflow命名空间是否可用。其 doctest 也标注依赖['numpy', 'tensorflow']等模块,与文档描述一致。
代码生成(Code Generation)相关依赖
SymPy 可以为大量语言生成代码(见 sympy/codegen 与 sympy/printing)。重点澄清:这些依赖不是"支持的语言清单"——对大多数语言,SymPy 只生成字符串形式的代码,因此不需要安装对应语言的编译器;依赖通常只在"把生成的代码自动编译为 Python 可调用函数"时才需要。lambdify是该模式的特殊情况,其依赖已在上节列出。
Autowrap 工具链
- NumPy 及其 f2py 子包:可用于
autowrap()/ufuncify()生成 Python 函数。 - Cython:可作为
autowrap/ufuncify的后端,也用于部分sympy.codegen测试中的示例编译。 - 编译器(Compilers):
autowrap、ufuncify及相关函数依赖编译器把生成代码编译为函数。绝大多数主流 C、C++、Fortran 编译器都受支持,包括 Clang/LLVM、GCC、ifort。
代码打印器(Code Printers)
多数代码打印器只生成 Python 字符串,无需对应库或编译器;少数例外:
- llvmlite:模块
sympy.printing.llvmjitcode(见 sympy/printing/llvmjitcode.py)支持从 SymPy 表达式生成 LLVM JIT,其llvm_callable()函数生成可调用函数,依赖 llvmlite(LLVM 的 Python 封装)。 - TensorFlow:模块
sympy.printing.tensorflow(见 sympy/printing/tensorflow.py)的tensorflow_code()确实生成 Python 字符串,与上述两个模块不同。但若本机装有 TensorFlow 会被导入以自动检测版本;未安装时则假定使用最新的受支持版本。
仅测试用依赖
- Wurlitzer:用于捕获 C 扩展的输出,仅被
sympy.codegen的部分测试使用,不参与任何终端用户功能;未安装时相关测试被跳过。 - Cython:部分
sympy.codegen测试用它编译示例。 - 编译器:前面提到的各种编译器在已安装时用于 codegen 与 autowrap 测试。
统计采样相关依赖
sympy.stats.sample()需要至少一个外部库来产生分布样本:
- SciPy:
sample(library='scipy')为默认后端,使用scipy.stats。 - NumPy:
sample(library='numpy')使用 NumPy random 模块。 - PyMC:
sample(library='pymc')使用 PyMC 采样。
实现位于 sympy/stats 子模块(如 sympy/stats/rv_interface.py)。
可选的 SymEngine 后端
SymEngine 是一个 C++ 编写的高速符号运算库,其 Python 绑定可作为 SymPy core 的可选后端:
- 安装绑定:
pip install symengine或conda install -c conda-forge python-symengine; - 以环境变量运行:
USE_SYMENGINE=1。
源码 sympy/core/backend.py 的实现是:
USE_SYMENGINE = os.getenv('USE_SYMENGINE', '0') USE_SYMENGINE = USE_SYMENGINE.lower() in ('1', 't', 'true') if USE_SYMENGINE: from symengine import (Symbol, Integer, sympify as sympify_symengine, ...) else: from sympy.core.add import Add ...当前该后端只被sympy.physics.mechanics与sympy.liealgebras模块使用,但也可以直接通过sympy.core.backend与其交互:
>>> from sympy.core.backend import Symbol >>> # 若配置了 USE_SYMENGINE 环境变量,将创建 SymEngine 的 Symbol 对象; >>> # 否则是普通的 SymPy Symbol 对象。 >>> x = Symbol('x')SymEngine 后端目前仍属实验性,启用后部分 SymPy 函数可能无法正常工作。backend.py中还包含针对 SymEngine 0.7.0 矩阵simplify()行为不一致问题的兼容函数_simplify_matrix,可作为其未完全成熟的一个佐证。
Sage 集成
Sage 是聚合了大量开源数学库的数学软件,SymPy 是其所用库之一。大部分 SymPy 与 Sage 的对接代码位于 Sage 自身,SymPy 只提供少量_sage_方法用于基础的 wrapper 搭建,这些方法通常只应由 Sage 内部调用。从仓库结构看,_sage_相关代码散布在各表达式类中(例如sympy/core/expr.py等处的_sage_方法),与文档描述一致。
开发依赖
SymPy 的常规开发不需要 Python 与 mpmath 之外的任何额外依赖。
获取源码
- git:SymPy 源码使用 git 版本控制。从 git 获取开发版 SymPy 的方式见安装指南与贡献者指南(doc/src/contributing/introduction-to-contributing.md)。
运行测试
基础测试不要求额外依赖,但上文的可选依赖中有相当一部分是"某些测试"所需的。未安装时,依赖它们的测试应当被跳过,方式有两种:
- 调用
sympy.testing.pytest.skip()(见 sympy/testing/pytest.py); - 在测试文件级设置
skip = True跳过整个文件。
测试与库代码中对可选模块的导入一律使用import_module()。其实现位于 sympy/external/importtools.py,核心行为如下:
- 模块未安装时返回
None(并可选发出UserWarning); - 支持
min_module_version(通过module_version_attr指定版本属性,默认__version__,必要时用module_version_attr_call_args调用函数取值)与min_python_version双重版本门槛; - 通过
catch参数额外捕获导入时抛出的非ImportError异常(例如 matplotlib 在无显示环境抛RuntimeError); - 模块级开关
WARN_NOT_INSTALLED(默认 False)与WARN_OLD_VERSION(默认 True)可全局控制警告行为;设置环境变量SYMPY_DEBUG=True会同时打开两类警告,便于调试。
具体测试依赖:
- pytest:并非 SymPy 测试套件的必需依赖。SymPy 自带测试运行器(在源码目录执行
python bin/test,或调用sympy.test());当然也可用 pytest 替代,但测试代码应使用 sympy/testing/pytest.py 中的包装函数而非直接使用 pytest 函数。仓库根目录 pyproject.toml 的[tool.pytest.ini_options]配置了默认排除slow/tooslow标记用例、限定testpaths = ["sympy", "doc/src"]等行为,可直接运行。 - cloudpickle:比内置
pickle更高效地序列化 SymPy 对象;仅 sympy/utilities/tests/test_pickling.py 中的部分测试依赖它。 - hypothesis:SymPy 测试套件的必需依赖,用于基于属性的测试。
- 环境变量相关:SymPy 的测试基础设施还支持
SYMPY_GROUND_TYPES、USE_SYMENGINE等开关,可结合上文验证不同 ground type 下的行为。
构建文档
构建文档需要额外的若干依赖(Sphinx 及插件、sphinx-lint等),详见文档构建指南(doc/README.rst 与 doc/src/contributing/docstring.rst)。只有当你正在为 SymPy 贡献文档、需要验证 HTML/PDF 渲染效果时才需要安装它们;只想阅读开发版文档的用户可直接访问在线 dev 构建。
运行基准测试
基准测试代码托管在独立仓库,其运行方法由该仓库的 README 说明。asv(Airspeed Velocity)是运行基准测试的包,安装的包名就是asv。SymPy 仓库内的基准测试代码位于 sympy/benchmarks 与各模块的benchmarks/目录(如 sympy/core/benchmarks)。基准测试也会在 GitHub Actions CI 上自动运行,普通贡献者一般无需自行执行,除非要复现结果或新增基准用例。
总结:如何选择安装
| 你的使用场景 | 需要安装 |
|---|---|
| 仅导入并使用 SymPy 基本功能 | mpmath(自动随 SymPy 安装) |
| 追求大整数/多项式运算性能 | gmpy2(推荐) |
| 交互式使用 / 笔记本 | IPython、Jupyter(可选 Qt Console + LaTeX) |
使用preview()渲染图片 | LaTeX 发行版(TeX Live / MiKTeX) |
| 使用 LaTeX/Autolev 解析 | antlr 运行时(版本须匹配 4.10)或 lark |
| 使用 C/Fortran 解析 | Clang Python 绑定 / LFortran |
| 加速 SAT 求解 | pycosat 或 pysat |
| 绘图 | matplotlib(必需)、pyglet(可选) |
| lambdify 数值后端 | numpy、scipy、cupy、jax、tensorflow、numexpr 按需 |
| autowrap / ufuncify | numpy+f2py、cython、C/C++/Fortran 编译器 |
| sympy.stats 采样 | scipy(默认)、numpy、pymc 之一 |
| 启用 SymEngine 后端 | python-symengine +USE_SYMENGINE=1 |
| 运行完整测试套件 | pytest(或内置bin/test)、hypothesis(必需)、cloudpickle、wurlitzer 等 |
| 构建文档 / 运行基准 | Sphinx 工具链 / asv |
核心原则贯穿始终:SymPy 保持极低的依赖门槛,所有可选依赖都通过import_module()等机制按需探测、优雅降级。理解这份依赖地图,无论你是普通用户、数值计算工程师还是 SymPy 贡献者,都能精准安装所需组件、避免不必要的依赖冲突,并在 CI 与本地环境之间保持一致的行为。
【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考