首頁 >後端開發 >Python教學 >如何確保自訂 Python 類別的一致且穩健的等價比較,尤其是在處理子類別和集合時?

如何確保自訂 Python 類別的一致且穩健的等價比較,尤其是在處理子類別和集合時?

Linda Hamilton
Linda Hamilton原創
2024-11-09 04:50:02429瀏覽

How do you ensure consistent and robust equivalence comparisons for custom Python classes, especially when dealing with subclasses and sets?

Python 類別中等價比較的優雅方法

在Python 中,自訂類別可以實作__eq__ 和__ne__ 方法來定義== 和!= 運算子的等價性,分別。雖然比較字典屬性的傳統方法很簡單,但它有一定的限制。

更精緻的方法

考慮以下場景:

class Number:
    def __init__(self, number):
        self.number = number

n1 = Number(1)
n2 = Number(1)

# Default comparison fails: they are different objects
assert n1 != n2

解決此問題,我們可以重寫__eq__ 方法:

class Number:
    def __init__(self, number):
        self.number = number

    def __eq__(self, other):
        if isinstance(other, Number):
            return self.number == other.number
        return False

但是,對於Python 2,我們還需要實作__ne__來確保交換行為:

class Number:
    def __init__(self, number):
        self.number = number

    def __eq__(self, other):
        if isinstance(other, Number):
            return self.number == other.number
        return False

    def __ne__(self, other):
        return not self.__eq__(other)

這確保 n1 == n2計算結果為 True,如預期。

子類等效

引入子類會使等效比較複雜化:

class SubNumber(Number):
    pass

n3 = SubNumber(1)

# Subclass comparison fails for classic-style classes
assert n1 == n3  # False (for classic-style classes)
assert n3 == n1  # True

# Non-commutative comparison
assert n1 != n3  # True (for classic-style classes)
assert n3 != n1  # False

對於經典樣式的類,根據第一個操作數的類型,導致非交換行為。為了解決這個問題,我們可以為不支援的運算元類型傳回NotImplemented,它將比較委託給其他運算元的方法:

def __eq__(self, other):
    if isinstance(other, Number):
        return self.number == other.number
    return NotImplemented

散列和集合

最後,請請注意,集合使用物件標識符哈希,這可能會導致不正確的結果:

assert len(set([n1, n2, n3])) == 3  # Incorrectly reports 3 unique numbers

要解決此問題,我們可以重寫__hash__ 方法:

def __hash__(self):
    return hash(tuple(sorted(self.__dict__.items())))

透過這些增強功能,等價性和唯一性行為變得正確,並且一致,確保集合中的穩健比較和準確表示:

assert len(set([n1, n2, n3])) == 1
assert len(set([n1, n2, n3, n4])) == 2

以上是如何確保自訂 Python 類別的一致且穩健的等價比較,尤其是在處理子類別和集合時?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn