Ném TypeError: unhashable type.
Python 3 tự đặt __hash__ = None cho class nào override __eq__ mà không khai báo __hash__.
python
class User:
def __init__(self, uid): self.uid = uid
def __eq__(self, other):
return isinstance(other, User) and self.uid == other.uid
{User(1)} # TypeError: unhashable type: 'User'Lý do là hợp đồng giữa hash và equality:
- a == b thì bắt buộc hash(a) == hash(b).
- Hash phải không đổi trong suốt vòng đời object; nếu hash đổi sau khi object đã nằm trong dict/set thì không tra cứu lại được nữa.
Nếu tự định nghĩa __eq__ mà vẫn giữ hash mặc định (theo địa chỉ id), hai object bằng nhau lại có hash khác nhau → dict/set hỏng ngầm. Nên Python chọn báo lỗi thay vì để sai âm thầm.
python
class User:
__slots__ = ("uid",)
def __init__(self, uid): self.uid = uid
def __eq__(self, other):
return isinstance(other, User) and self.uid == other.uid
def __hash__(self):
return hash(self.uid) # hash only immutable identity fieldsTương tự với dataclass: @dataclass (mặc định eq=True) là unhashable; muốn hashable thì dùng @dataclass(frozen=True).