2010-11-03 50 views
2

[Python的3.1]子類浮強制定點印刷精度在Python

我在this answer跟進:

class prettyfloat(float): 
    def __repr__(self): 
    return "%0.2f" % self 

我知道我需要跟蹤我的浮動文字的(即用prettyfloat(3.0)等代替3.0等),那很好。

但是,每當我做任何計算,prettyfloat對象被轉換爲float

解決它的最簡單方法是什麼?

編輯:

我需要正好兩個十進制數字;我需要在整個代碼中使用它,包括在哪裏打印一個包含float值的字典。這使得任何格式化功能都很難使用。

我不能使用Decimal全局設置,因爲我想要完全精確的計算(只打印2個小數點)。

@Glenn Maynard:我同意我不應該重寫__repr__;如果有的話,它將只是__str__。但由於以下幾點,這是一個有爭議的問題。

@Glenn Maynard和@singularity:我不會繼承子類float,因爲我同意它看起來會非常醜陋。

我會停止嘗試變得聰明,只要打印一個函數就可以打印float。雖然我很傷心,我不能在內建類float中覆蓋__str__

謝謝!

+0

格式很好的最簡單的方法可能是使用'decimal.Decimal'。那有什麼問題? – 2010-11-03 23:56:22

+0

我還沒有看到像float這樣的核心類型的子類化是正確的。 – 2010-11-04 00:02:09

+0

@ S.Lott我需要正好兩位十進制數字;我在整個代碼中都需要它,包括在哪裏打印一個包含浮點值的字典。 @Glenn梅納德我沒有太多的希望,無論是:(只是想也許有一個乾淨的方式,使其工作。 – max 2010-11-04 00:02:13

回答

5

我看看你接下來的答案,我認爲你很困惑數據及其表示

@Robert Rossney建議繼承float所以你可以map()標準的迭代,不摻假floatsprettyfloats爲了顯示

# Perform all our computations using standard floats. 
results = compute_huge_numbers(42) 
# Switch to prettyfloats for printing. 
print(map(prettyfloat, results)) 

換句話說,你不應該(和你不應該)在你的代碼中使用prettyfloat作爲float的替代品。

當然,從float繼承來解決這個問題是矯枉過正,因爲它是一個代表性的問題,而不是數據問題。一個簡單的功能就足夠了:

def prettyfloat(number): 
    return "%0.2f" % number # Works the same. 

現在,如果它不是表示畢竟,和你真正想達到什麼是定點計算限制在你的代碼到處小數點後兩位,這是another story完全。

3

,由於prettyfloat (op) prettyfloat不返回prettyfloat

例如:

>>> prettyfloat(0.6) 
0.60 # type prettyfloat 
>>> prettyfloat(0.6) + prettyfloat(4.4) 
5.0 # type float 

解決方案,如果你不想手動施放每一個操作結果prettyfloat如果你仍然想使用prettyfloat是覆蓋所有的操作符。

通過這樣做,我認爲你將不得不也從prettyfloat名稱更改爲uglyfloat :)例如與運營商__add__(這是醜陋的)

class prettyfloat(float): 
    def __repr__(self): 
     return "%0.2f" % self 
    def __add__(self, other): 
     return prettyfloat(float(self) + other) 

>>> prettyfloat(0.6) + prettyfloat(4.4) 
5.00 

,希望這將有助於

+1

作爲一種疑難問題的例子,你會遇到這樣的事情,結果prettyfloat的'(1.12345)+ 1.12345'和'1.12345 + prettyfloat(1.12345)'有很大的不同。 – 2010-11-04 00:21:51

+0

葉氏那爲什麼他不應該這樣做,他可以由每個時間來解決這個問題做一些類型檢查使之更醜陋:) – mouad 2010-11-04 00:32:28

1

使用decimal。這是它的用途。

>>> import decimal 
>>> decimal.getcontext().prec = 2 
>>> one = decimal.Decimal("1.0") 
>>> three = decimal.Decimal("3.0") 
>>> one/three 
Decimal('0.33') 

...除非你真的想用全精密工作到處漂浮在你的代碼,但打印出來四捨五入至小數點後兩位。在這種情況下,您需要重新編寫打印邏輯。

+1

這正在改變價值的精確度,而不僅僅是如何顯示,這是非常不同的。我還必須嚴格質疑具有全局配置的模塊的設計能力。如果您使用在後臺使用此模塊的庫(或多個庫),很難想象上下文配置更改可能會叮咬衆多難以理解和難以修復的方法。 – 2010-11-04 00:28:45

+0

(我希望他們能夠修復網站缺陷,讓人們編輯答案,而不會讓他們顯示爲已編輯。) – 2010-11-04 00:29:56

+0

@Glenn:我相信在張貼後您可以編輯而不需要將您的帖子標記爲已編輯的窗口之後有一個短窗口。你確實是正確的,當然=)。 – katrielalex 2010-11-04 08:24:18