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