2015-03-31 80 views
1

我想爲我的複合對象(即由其他(可能是複合)對象組成的對象)提供豐富的表示。但是,因爲我的代碼從根本上處理了高精度數字(請不要問我爲什麼不使用雙精度數),最終我得到的結果如下所示:http://pastebin.com/jpLgAfxC。只是堅持默認__repr__會更好嗎?__repr__ for(large)composite objects

+0

這聽起來有些明顯,但這樣的事情是你想讓對象表現自己的方式。 – 2015-03-31 18:16:21

+0

請不要在這裏粘貼整個對象,放一部分對象並使用pastebin或其他替代方法來整個對象。 – 2015-03-31 18:17:27

+0

我嘗試去做一個有信息的表示,可以用'eval'ed – 2015-03-31 18:22:35

回答

2

是否有詳細的repr取決於你想完成什麼。對於複雜或複合對象,我知道,我寧願以下幾點:

Point(x=1.12, y=2.2, z=-1.9) 
<__main__.Point object at 0x103011890> 

他們都告訴我的對象是什麼類型,但只有第一個是明確涉及的所有(相關)的值,並避免只與最稀有場合相關的低級信息。

我喜歡看到真正的價值。但是,你是一個特例,因爲你的價值觀是如此可怕堆積如山:

72401317106217603290426741268390656010621951704689382948334809645 
87850348552960901165648762842931879347325584704068956434195098288 
38279057775096090002410493665682226331178331461681861612403032369 
73237863637784679012984303024949059416189689048527978878840119376 
5152408961823197987224502419157858495179687559851 

,他們不能成爲大多數開發或調試的目的。例如,我確定有時候需要完整的序列化 - 例如發送到文件和從文件發送。但那些必須是相當罕見的,不是嗎?我無法想象你真的記住所有309位,或可判斷上述號碼相同下面的一個目測:

72401317106217603290426741268390656010621951704689382948334809645 
87850348552960901165648762842931879347325584704068956434195098288 
38279057775096090002410493665682226331178331461681861612403032369 
73327863637784679012984303024949059416189689048527978878840119376 
5152408961823197987224502419157858495179687559851 

他們是不一樣的。但是除非你是Spock或者終結者,否則你一眼就不會知道。 (實際上,我已經在這裏變得更容易了,爲了避免水平滾動,長度纏繞。)

所以我會推薦(大量)縮短它們的表示,使輸出更易於處理。這就像每次打印一個Chapter對象時打印整個章節文本。矯枉過正。

相反,嘗試更短,更容易使用的東西。截斷和/或省略號是有用的。例如

72401...59851 
7240131710... 

您也可以使用對象ID。如果您的高精密型爲HP,則:

HP(0x103011890) 

至少這樣你就可以告訴他們分開。然而,使用對象標識符的一個醜陋之處在於,對象可能在邏輯上是等價的,但是如果您創建具有相同邏輯值的多個對象,則它們將具有不同的ID,因此在不相同時會顯示不同的ID。你可以通過創建你自己的短散列函數來解決這個問題。哈希算法有一些技巧,但對於程序員來說,即使是簡單的東西也可以工作。例如。:

import binascii, struct 

def shorthash(s): 
    """ 
    Given a Python value, produce a short alphanumeric hash that 
    helps identify it for debugging purposes. A riff on 
    http://stackoverflow.com/a/2511059/240490 
    Enhanced to remove trailing boilerplate, and to work 
    on either Python 2 or Python 3. 
    """ 
    hashbytes = binascii.b2a_base64(struct.pack('l', hash(s))) 
    return hashbytes.decode('utf-8').rstrip().rstrip("=") 

在高精密級然後定義您的再版:

def __repr__(self): 
    clsname = self.__class__.__name__ 
    return '{0}({1}).format(clsname, shorthash(self.value)) 

哪裏self.value無論是本地屬性,屬性或方法創建多百位值。如果您繼承int,這可能只是self

,它會給你:

HP(Tea+5MY0WwA) 

兩個巨大的,幾乎相同的數字上面?使用這種方案,他們渲染出:

HP(XhkG0358Fx4) 
HP(27CdIG5elhQ) 

這明顯不同。你可以將它與一些值表示法結合起來。例如。幾個備選方案:

HP(~7.24013e308 @ XhkG0358Fx4) 
HP(dig='72401...59851', ndigits=309, hash='XhkG0358Fx4') 

你會發現這些短值在調試環境中更加有用。當然,您可以圍繞一種方法或屬性(例如.value,.digits.alldigits)針對那些需要每個最後一位的情況,但將常見情況定義爲更容易使用的情況。

+0

這是非常有用的。謝謝。 – 2015-03-31 21:30:17

0

謝謝德米安爲指針https://docs.python.org/2/reference/datamodel.html#object.repr,具體是:

這通常用於調試,所以重要的是, 表示是信息豐富和明確的。

http://pastebin.com/jpLgAfxC在這種情況下可能是最好的__repr__

+1

我不同意309位數值是最好的repr。當然,這些信息豐富而且毫不含糊。這是完整的牛津英語詞典。大型文本對於人類立即理解和「差異」而言本質上是困難的。對於寫入永久存儲器,是打印所有數字。爲了調試,我推薦更短的一些。 – 2015-03-31 19:41:16