如何自定义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
相关产品推荐
相关产品推荐

