2011-11-03 35 views
-1

有人可以告訴我如何使用這段代碼?我不確定我想問什麼問題,我只想定義需要與之一起玩的課程,以及我可以提供給解釋者的其他命令。Python - 不可變類型的例子

這真的是讓我的頭旋轉,因爲沒有其他支持代碼,我認爲它可能是一個元類的用法。

謝謝

class RoundFloat(float): 
    def __new__(cls, val): 
     return float.__new__(cls, round(val, 2)) 
+0

如果你不知道問題是什麼,我們怎麼知道什麼/如何回答? –

+0

@ LasseV.Karlsen:你糾正了OP的代碼,這可能是OP所需要的,因爲縮進在Python中很重要。我相信你可能在編輯中回答了這個問題;) – Tadeck

+0

夥計們,謝謝你的迴應。我剛開始用wesley chuns的書學習OOP,這對初學者來說並不是最好的。我沒有意識到它與內建類型的float有關,但它引用了另一個類並傳遞了一個實例或其他東西。這個oop的東西超級難。 – user1027217

回答

4

稱爲__new__的方法是類構造函數。不要將它與__init__混淆,這是類初始化程序;不同之處在於__new__在您擁有該對象的實例之前調用,並且必須創建並返回實例,而在創建該對象後調用__init__

通常,當您繼承子類時,您只需重寫初始化程序以執行自己的初始化,但如果您繼承了不可變對象,那麼通常不起作用,因爲在構建對象後無法更改其實際值。在這種情況下,代碼正在改變float的構造方式,因此它覆蓋了float.__new__,然後使用修改的參數顯式調用它。

整個類是完全是浪費時間,如果你想創建一個圓形的浮動只是這樣做:

def rounded_float(f): return round(f, 2) 

或:

from functools import partial 
rounded_float = partial(round, ndigits=2) 

,並在這兩種情況下調用rounded_float返回四捨五入爲2位數的值。 還記得當你使用這個函數,rounded_float(1.0/3.0)並不完全給你0.33它只是給你最近的浮點表示。如果您希望確切的值用於計算目的,請使用Decimal類,但如果它用於輸出,則只需格式化輸出上的數字。

+0

return round(** f **,2) – eyquem

+0

Thanks @eyquem,fixed。 – Duncan

+0

類: 高清__init __(自我,返回): self.returned =返回 打印self.returned 類的例子(一): 高清__new __(CLS,VAL): 返回.__新__(CLS) – user1027217

2

首先,縮進我看到的是不正確。該方法(構造函數)的定義應縮進:

class RoundFloat(float): 
    def __new__(cls, val): 
     return float.__new__(cls, round(val, 2)) 

其次,使用它你可以寫這樣的事情:

a = RoundFloat(3.1236589) 

,然後,如果你這樣做:

print a 

你將會收到:

3.12

這是什麼應該在這裏預期(手段:是正確的行爲)。

是你要求的嗎?讓我知道。

+0

__new__做什麼?我已經搜索的示例參考元類 – user1027217

+0

@ user1027217:向我展示這些示例。 '__new__'方法是一個構造函數 - 在'float .__ new __()'的情況下,您可以調用'float'類的構造函數。這足夠清楚了嗎? – Tadeck

4

這裏沒什麼好瘋狂的。我會批評評論。雖然它的格式應該是這樣的:

# Inherit from the built in type 'float', 
# so that this can be used anywhere a float can 
class RoundFloat(float): 
    # __new__ takes care of actually creating the object 
    def __new__(cls, val): 
     # Pass it off to the float initializer, but round the value first 
     return float.__new__(cls, round(val, 2)) 

它真的實現該總是四捨五入至小數點後2位浮點值的只是一個快捷方式。

1

你使用這樣的:

a = RoundFloat(10.256) 

如果現在打印:

10.26 
1

如果你希望所有的一些情況要四捨五入浮動,那麼定義的類RoundFloat是OK:數字將顯示爲圓形的花車,將BE四捨五入浮動。
這意味着如果您執行的操作涉及兩個這樣的數字,例如+ - x /,則操作的結果將不會是涉及未包含值的結果的四捨五入值。

也許這是你想要的。

,但如果你希望:

1)與保持其準確值號工作同時顯示在一個圓形的方式,你必須只覆蓋__str__

2)的涉及兩個此類實例的操作的結果本身就是這樣一個實例,您還必須覆蓋操作__add__,__div__

您必須採取其他方式,如下面定義的類Floot

以下代碼比較了兩種情況下的添加結果。

class Floot(float): 
    cut = 4 
    def __init__(self,x): 
     self = x 
    def __str__(self): 
     return ('%%.%df' % Floot.cut) % self 
    def __add__(self,y): 
     return Floot(super(Floot,self).__add__(y)) 
    def __sub__(self,y): 
     return Floot(super(Floot,self).__sub__(y)) 
    def __div__(self,y): 
     return Floot(super(Floot,self).__div__(y)) 
    def __mul__(self,y): 
     return Floot(super(Floot,self).__mul__(y)) 
    def __pow__(self,y): 
     return Floot(super(Floot,self).__pow__(y)) 


class RoundFloat(float): 
    def __new__(cls, val): 
     return float.__new__(cls, round(val, 4)) 


a = 5.1275407 
b = 0.7003208 


print 'class Floot\n***********' 

aa = Floot(a) 
print 'a    : ',a 
print 'aa = Floot(a) : ',aa 

bb = Floot(b) 
print '\nb    : ',b 
print 'bb = Floot(b) : ',bb 

c = a+b 
cc = aa + bb 
print '\nc = a + b  : ',c 
print 'cc = aa+bb  : ',cc 

print '\nround(c ,4)  : ',round(c,4) 
print 'round(cc,4)  : ',round(cc,4) 

print ('\nc - round(c ,4) : %.10f' % (c - round(c ,4))).rstrip('0') 
print ('cc - round(cc,4) : %.10f' % (cc - round(cc,4))).rstrip('0') 




print '\n\nclass RoundFloat\n****************' 

aa = RoundFloat(a) 
print 'a     : ',a 
print 'aa = RoundFloat(a) : ',aa 

bb = RoundFloat(b) 
print '\nb     : ',b 
print 'bb = RoundFloat(b) : ',bb 

c = a+b 
cc = aa + bb 
print '\nc = a + b   : ',c 
print 'cc = aa+bb   : ',cc 

print '\nround(c ,4)   : ',round(c,4) 
print 'round(cc,4)   : ',round(cc,4) 

print ('\nc - round(c ,4) : % .10f' % (c - round(c ,4))).rstrip('0') 
print ('cc - round(cc,4) : % .10f' % (cc - round(cc,4))).rstrip('0') 

該FLOOT(5.1275407)+ FLOOT(0.7003208)顯示爲5.8279,儘管被顯示爲5.1275和FLOOT(0.7003208)的事實FLOOT(5.1275407)顯示爲0.7003的事實,暴露出一個事實,即實際這些Floot實例的值比它們的顯示更精確。

cc - round(cc,4)c - round(c,4)相同值的事實背叛一樣的:FLOOT(A)+ FLOOT(B)A + B有實際上是一樣的價值,儘管他們是如何顯示