Rumah > Artikel > pembangunan bahagian belakang > Bagaimanakah anda memastikan perbandingan kesetaraan yang konsisten dan mantap untuk kelas Python tersuai, terutamanya apabila berurusan dengan subkelas dan set?
Dalam Python, kelas tersuai boleh melaksanakan kaedah __eq__ dan __ne__ untuk menentukan kesetaraan untuk operator == dan !=, masing-masing. Walaupun kaedah tradisional untuk membandingkan atribut kamus adalah mudah, ia memberikan batasan tertentu.
Pertimbangkan senario berikut:
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
Untuk menangani isu ini , kita boleh mengatasi kaedah __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
Walau bagaimanapun, untuk Python 2, kita juga perlu melaksanakan __ne__ untuk memastikan tingkah laku komutatif:
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)
Ini memastikan n1 == n2 menilai kepada Benar, seperti yang dijangkakan.
Memperkenalkan subkelas merumitkan perbandingan kesetaraan:
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
Untuk kelas gaya klasik, kaedah perbandingan digunakan berdasarkan jenis operan pertama, yang membawa kepada tingkah laku bukan komutatif. Untuk menangani perkara ini, kami boleh mengembalikan NotImplemented untuk jenis operan yang tidak disokong, yang mewakilkan perbandingan kepada kaedah operan lain:
def __eq__(self, other): if isinstance(other, Number): return self.number == other.number return NotImplemented
Akhir sekali, ambil perhatian bahawa set menggunakan pengecam objek untuk pencincangan, yang boleh membawa kepada hasil yang salah:
assert len(set([n1, n2, n3])) == 3 # Incorrectly reports 3 unique numbers
Untuk menyelesaikan masalah ini, kami boleh mengatasi kaedah __hash__:
def __hash__(self): return hash(tuple(sorted(self.__dict__.items())))
Dengan peningkatan ini, tingkah laku kesetaraan dan keunikan menjadi betul dan konsisten, memastikan perbandingan yang mantap dan perwakilan yang tepat dalam set:
assert len(set([n1, n2, n3])) == 1 assert len(set([n1, n2, n3, n4])) == 2
Atas ialah kandungan terperinci Bagaimanakah anda memastikan perbandingan kesetaraan yang konsisten dan mantap untuk kelas Python tersuai, terutamanya apabila berurusan dengan subkelas dan set?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!