2013-08-22 86 views
4

有沒有確定兩個任意python對象相等的最佳實踐? 假設我爲某種對象編寫容器,並且需要確定新對象是否與存儲在容器中的舊對象相同。Python中平等的最佳實踐

問題是我不能使用「是」,因爲這將只檢查變量是否綁定到同一個對象(但我們可能有一個對象的深層副本,這在我的意義上等於它的原始) 。我也不能使用「==」,因爲其中的一些對象返回一個元素相等的數組,比如numpy數組。

是否有確定任何類型對象相等的最佳做法? 例如

repr(objectA)==repr(objectB) 

夠了嗎?

或者是常見的使用方法:

numpy.all(objectA==objectB) 

如果對象A ==對象B的計算結果爲 「[]」

乾杯, 羅伯特

編輯的可能失敗:

好的,關於第三條評論,我詳細說明了 「你對」平等對象「的定義是什麼?」

從強烈的意義上說,我沒有任何平等的定義,我寧願讓對象決定他們是否平等。問題是,據我所知,eq或==沒有很好的商定標準。該語句可以返回數組或各種事物。

我想到的是讓一些操作員可以稱其爲eq和「is」之間的SEQ(強相等)。 SEQ是優於eq從某種意義上說,它總是會計算一個布爾值(例如numpy數組可能意味着所有元素都是相等的),並確定這些對象是否認爲自己是平等的。但是,從內存中不同的對象也可以相等的意義上說,SEQ不如「是」。

+0

對於記錄,'numpy.all([])'是'True',因爲它應該是。 –

+0

我們在Python中進行「豐富的比較」所付出的代價是我們無法再編寫泛型相等運算符。 –

+2

我不知道我明白。你不想比較引用(不是'is'),但你不想深入比較(沒有「元素相等」)? 「平等對象」的定義是什麼? – freakish

回答

2

我建議你寫一個自定義的遞歸平等檢查器,像這樣:

from collections import Sequence, Mapping, Set 
import numpy as np 

def nested_equal(a, b): 
    """ 
    Compare two objects recursively by element, handling numpy objects. 

    Assumes hashable items are not mutable in a way that affects equality. 
    """ 
    # Use __class__ instead of type() to be compatible with instances of 
    # old-style classes. 
    if a.__class__ != b.__class__: 
     return False 

    # for types that implement their own custom strict equality checking 
    seq = getattr(a, "seq", None) 
    if seq and callable(seq): 
     return seq(b) 

    # Check equality according to type type [sic]. 
    if isinstance(a, basestring): 
     return a == b 
    if isinstance(a, np.ndarray): 
     return np.all(a == b) 
    if isinstance(a, Sequence): 
     return all(nested_equal(x, y) for x, y in zip(a, b)) 
    if isinstance(a, Mapping): 
     if set(a.keys()) != set(b.keys()): 
      return False 
     return all(nested_equal(a[k], b[k]) for k in a.keys()) 
    if isinstance(a, Set): 
     return a == b 
    return a == b 

的假設,即哈希的對象不在影響平等的方式可變是相當安全的,因爲它會破壞類型的字典和設置這些對象是否被用作鍵。

+0

謝謝,這是一個有用的建議:) – SmCaterpillar