ImportError: cannot import name 'isclose'

ImportError: cannot import name 'isclose'

在单元测试我的 Python 模块时,我 运行 遇到了一个奇怪的错误:

⅔ 的构建正常通过,但其中一个无法从标准 math 库导入 isclose

错误重现如下:

==================================== ERRORS ====================================
______________________ ERROR collecting tests/test_yau.py ______________________
ImportError while importing test module '/home/travis/build/Benjamin-Lee/squiggle/tests/test_yau.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_yau.py:5: in <module>
    from math import isclose
E   ImportError: cannot import name 'isclose'
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
=========================== 1 error in 0.29 seconds ============================
The command "pytest --cov=squiggle" exited with 2.

同一目录中(或我的包中根本没有)没有名为 math.py 的文件。可能是什么原因造成的?

多次重新启动构建并没有修复这个错误,它只出现在 Python 3.4.

可以访问完整日志 here

我们可以从链接 "full log" 中得知,您是 运行 Python 3.4.6.

$ python --version
Python 3.4.6

math.isclose function was introduced in Python 3.5,这就是为什么你不能导入它的原因。安装更高版本的 Python(即 3.5+),或定义您自己的 isclose 函数,math 模块的定义几乎如下所示:

def isclose(a, b, rel_tol=1e-9, abs_tol=0.0):
    return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

# tests:
print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
print(isclose(0.1 + 0.2, 0.3))

# outputs:

0.30000000000000004
False
True

a and b: are the two values to be tested to relative closeness

rel_tol: is the relative tolerance -- it is the amount of error allowed, relative to the larger absolute value of a or b. For example, to set a tolerance of 5%, pass rel_tol=0.05. The default tolerance is 1e-9, which assures that the two values are the same within about 9 decimal digits. rel_tol must be greater than 0.0

abs_tol: is a minimum absolute tolerance level -- useful for comparisons near zero.

pytest 具有 approx 函数,用于测试两个数字的近似相等性,可用于任何 python 版本。断言

assert math.isclose(a, b, rel_tol=rt, abs_tol=at)

因此可以替换为

assert a == pytest.approx(b, rel=rt, abs=at)