我有試圖處理與4位小數精度數大量的Python代碼,我堅持使用Python 2.4的原因有很多。該代碼做了非常簡單的數學運算(其信用管理代碼大多需要或添加積分)惡蟒十進制/浮
它混合使用float和Decimal(MySQLdb爲SQL DECIMAL類型返回Decimal對象)。在使用過程中出現了一些奇怪的錯誤之後,我發現所有的根本原因都是代碼中浮點數和小數點進行比較的幾個地方。
我得到的情況是這樣的:
>>> from decimal import Decimal
>>> max(Decimal('0.06'), 0.6)
Decimal("0.06")
現在我擔心的是,我可能無法趕上所有此類案件中的代碼。 (一個普通的程序員將繼續做x> 0而不是x>十進制('0.0000'),這是很難避免)
我想出了一個補丁(靈感來自python 2.7中十進制包的改進) 。
import decimal
def _convert_other(other):
"""Convert other to Decimal.
Verifies that it's ok to use in an implicit construction.
"""
if isinstance(other, Decimal):
return other
if isinstance(other, (int, long)):
return Decimal(other)
# Our small patch begins
if isinstance(other, float):
return Decimal(str(other))
# Our small patch ends
return NotImplemented
decimal._convert_other = _convert_other
我只是做了一個非常早期的裝載庫,它會通過允許浮動到十進制轉換比較之前(以避免撞到到對象比較Python的默認對象)將十進制包行爲。
,因爲它修復了一些浮法的四捨五入情況下,我專門用於「海峽」,而不是「再版」。例如。
>>> Decimal(str(0.6))
Decimal("0.6")
>>> Decimal(repr(0.6))
Decimal("0.59999999999999998")
現在我的問題是: 我錯過了什麼嗎?這相當安全嗎?或者我在這裏打破了什麼? (我想到了包的作者有很強的理由,以避免花車這麼多)
只需注意「return NotImplemented」來自decimal.py包本身。我添加的兩條線是在評論之間。然而,我同意你的方法,在這個實現中,python允許在我們假設都是數字的對象之間進行邏輯上瘋狂的比較。嗯,另一個想法可能是提出一個錯誤,而不是隱式轉換,但無論如何,我認爲我需要做點什麼... – 2010-11-15 08:30:57
'return NotImplemented'是正確的,並且是正確的,[documentation specified](http:// docs .python.org/reference/datamodel.html#emulating-numeric-types)返回一個不支持的比較。它允許Python試圖找到另一種做事的方式。 – aaronasterling 2010-11-15 08:35:48
使用術語「猴子修補」+1,這導致我的wikipedia這個詞,找到它來自「游擊隊補丁」,就像在游擊戰爭=)。 – Tommy 2013-10-17 03:11:20