2012-09-07 29 views
2

我需要創建一個虛擬對象來標記列表中的一個未初始化的元素(顯然,字典將是一個更好的選擇,但我需要一個列表,因爲內存限制嚴重)。創建一個獨特的虛擬對象

我想用這個目的具有以下屬性的對象:

  1. 它不評估爲等於任何其他對象,但本身。
  2. 除了從原始引用(通過賦值或參數傳遞)之外,不能創建對其的引用。

None滿足第一個但不是第二個要求(因爲它可能通過使用文字None在程序中的任何地方創建)。應工作,我認爲,

一種方法是:

UNINITIALIZED_VALUE = object() # will be compared for == through identity 
    a = [1, UNINITIALIZED_VALUE, 2, UNINITIALIZED_VALUE] 
    a[1] == a[3] # True 
    a[0] == UNINITIALIZED_VALUE # False 

我想仔細檢查我絕不錯過這種方法的任何潛在的問題。 (我正在使用Python 3.)

+0

除了你沒有用身份測試,你正在測試平等。使用'a [0]是UNINITIALIZED_VALUE'。現在,對於實際上沒有任何*差異的簡單對象*。但這是事情的原則。 ;-) –

+0

@LennartRegebro我添加了一個解答您的評論的答案。 – max

回答

3

不,這就是每個人都這麼做的。請注意,您不能在這樣的對象上設置任意屬性。

+0

Thx ..對於任意屬性,我通常使用'x = lambda:0'。這個可以嗎? – max

+1

雖然有效,但通常我們會創建一個從'object'派生的具有空(即'pass')塊的新類並將其實例化。 –

0

我只是創建一個答案,因爲我需要更多的空間來回復@Lennart Regebro的有趣評論。他的評論讓我想到a[0] is UNINITIALIZED_VALUE還是a[0] == UNINITIALIZED_VALUE更合適。

我認爲這取決於我(開發人員設計UNINITIALIZED_VALUE)我是否承諾支持is==或兩者。畢竟,除非給出明確的承諾,否則用戶不應該承擔任何事情(因爲如果他依賴無證行爲,實施可能會改變並破壞他的代碼)。

而且我實際上認爲如果我(作爲設計者)承諾is==將用於測試如果該值未初始化,會更好。如果沒有對==支持,用戶將無法寫出這樣的事:

def remove_duplicates(list_): 
    return list(set(list_)) # requires that UNINITIALIZED_VALUE supports == 

這裏有一個小問題。作爲UNINITIALIZED_VALUE的設計者,我可以很容易地保證它在LHS(我最初的單線實現)中的==行爲正確。但是,我不能保證它在RHS上的行爲正確。畢竟,如果LHS上的對象對它的比較語義有瘋狂的侵略性,並且比較等同於所見即所得事物,那我就無能爲力了。可以說,這種攻擊行爲幾乎是一個錯誤;這就是爲什麼我認爲這是一個小問題。