You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自定义mpmath惰性常量?实现类似mpmath.pi的动态精度常量

问题

能不能像mpmath官方文档里的pi这类常量一样,自定义mpmath的惰性常量?也就是定义一个常量,它的值不是在定义时计算,而是在使用时根据当前精度计算(或者从缓存获取),得到mpf或mpc类型。期望实现的行为如下:

>>> from mpmath import *
>>> my_lazy_one_third = MyLazyMpMathConstantSomehow(lambda: mpf(1)/3)
>>> mp.dps = 15
>>> +pi
mpf('3.1415926535897931')
>>> +my_lazy_one_third
mpf('0.33333333333333331')
>>> mp.dps = 40
>>> +pi
mpf('3.141592653589793238462643383279502884197169')
>>> +my_lazy_one_third
mpf('0.3333333333333333333333333333333333333333352')

mpmath是否提供该功能?若不支持,使用Python其他构造实现的最简洁方式是什么?

回答

mpmath本身没有提供自定义这类惰性常量的公开接口,但它内置的pi等常量确实是基于惰性计算+精度缓存的逻辑实现的。

要实现自定义的惰性mpmath常量,最简洁的方式是用Python自定义类模拟该逻辑,核心是在取值时(比如触发运算符、类型转换时)才根据当前mp.dps计算结果,并缓存对应精度的值避免重复计算。

以下是一个可直接使用的实现:

from mpmath import mp, mpf

class LazyMpConstant:
    def __init__(self, compute_func):
        self.compute_func = compute_func
        self._cache = {}  # 缓存不同精度下的计算结果

    def __pos__(self):
        # 通过+运算符触发取值,和mpmath内置常量用法对齐
        current_dps = mp.dps
        if current_dps not in self._cache:
            self._cache[current_dps] = self.compute_func()
        return self._cache[current_dps]

    # 可选:添加其他魔法方法扩展使用场景
    def __float__(self):
        return float(+self)

# 用法示例
my_lazy_one_third = LazyMpConstant(lambda: mpf(1)/3)

mp.dps = 15
print(+mp.pi)
print(+my_lazy_one_third)

mp.dps = 40
print(+mp.pi)
print(+my_lazy_one_third)

这个实现的关键细节:

  • 用_cache字典存储不同精度对应的结果,避免重复计算相同精度的值
  • 重载__pos__方法(即单目+运算符)来触发计算逻辑,和示例中的用法完全匹配
  • 传入的compute_func是无参函数,负责生成对应精度的mpf/mpc对象

如果需要让自定义常量支持更多运算(比如直接参与加减乘除),可以继续重载__add__、__mul__等魔法方法,让它的行为更贴近mpmath内置常量。

内容的提问来源于stack exchange,提问作者Don Hatch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 13:43:14