[英]How does pytest.approx accomplish its magic?
pytest approx
函数看起来非常酷,正如他们在文档中所说的那样,它使用了一种非常直观的语法:
>>> from pytest import approx
>>> 0.1 + 0.2 == approx(0.3)
True
>>> 1 + 1e-8 == approx(1)
True
但这实际上是如何运作的呢? 在第一个例子中,假设左侧0.29999...
到0.29999...
,那么我怎样才能在右侧有一些评估等于它的东西呢? approx
函数是否知道如何查看==
运算符的左值? approx
实际上工作的事实看起来像纯粹的巫术,有人可以解释它是如何完成其整洁的小技巧的吗?
这是自定义__eq__
的标准数据模型挂钩。
下面简化的例子应该为你澄清“巫术”。
>>> class MyObj:
... def __eq__(self, other):
... print(self, "is being compared with", other)
... return "potato"
...
>>> obj = MyObj()
>>> 0.1 + 0.2 == obj
<__main__.MyObj object at 0xcafef00d> is being compared with 0.30000000000000004
'potato'
请注意, float.__eq__
将首次尝试处理此比较。 上面显示的行为,以及approx(0.3)
,主要依赖于float
明确“选择”与MyObj
实例进行比较的MyObj
。 它通过返回特殊值NotImplemented
:
>>> (0.1+0.2).__eq__(obj)
NotImplemented
对于实际的pytest实现,请查看python_api.py::ApproxScalar
。
从源代码我可以发现他们创建了相应的大约类。 例如,它们具有ApproxDecimal
, ApproxScalar
, ApproxMapping
等。 approx函数检查您传递的值的类型,然后为其分配已定义的相应近似类。
所以当你输入:
0.1 + 0.2 == approx(0.3)
大约将其改为:
0.1 + 0.2 == ApproxDecimal(0.3)
现在这些__repr__()
类实现相应的__eq__()
和__repr__()
函数,帮助python执行比较。 因此,他们能够在这些近似类中定义近似匹配的逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.