繁体   English   中英

pytest.approx如何实现其魔力?

[英]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

从源代码我可以发现他们创建了相应的大约类。 例如,它们具有ApproxDecimalApproxScalarApproxMapping等。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM