键必须是可哈希对象:与普通字典一样,键必须是可哈希的,键必须是可哈希的什么意思,可哈希就可以当键?普通字典形成对比,普通字典对其键保持强引用,会阻止键对象被垃圾回收,能举个例子比较下,弱引用和强引用直观看下WeakKeyDictionary 和普通字典的区别?
什么是"可哈希"的对象?
在Python中,"可哈希"意味着对象有一个固定的哈希值(通过__hash__()方法获得),并且在对象的生命周期内这个值不会改变。可哈希的对象必须同时实现__hash__()和__eq__()方法。
可哈希对象的特征:
不可变性:如整数、字符串、元组(只包含可哈希元素)
哈希值在其生命周期内不变
如果两个对象相等,它们的哈希值也必须相等
可哈希 vs 不可哈希示例:
python
# 可哈希的对象(可以作为字典键)
hashable_objects = [1, "hello", (1, 2), frozenset([1, 2])]
# 不可哈希的对象(不能作为字典键)
non_hashable_objects = [[1, 2], {"a": 1}, set([1, 2])]
import gc
class MyClass:
def __init__(self, name):
self.name = name
def __repr__(self):
return f"MyClass({self.name})"
# 创建两个字典进行对比
normal_dict = {} # 普通字典
weak_dict = weakref.WeakKeyDictionary() # 弱引用字典
# 创建一个对象
obj = MyClass("test_object")
# 将对象添加到两个字典中
normal_dict[obj] = "Normal dict value"
weak_dict[obj] = "Weak dict value"
print("初始状态:")
print(f"普通字典: {list(normal_dict.keys())}")
print(f"弱引用字典: {list(weak_dict.keys())}")
# 删除对对象的引用
del obj
# 强制进行垃圾回收
gc.collect()
print("\n删除对象引用并垃圾回收后:")
print(f"普通字典: {list(normal_dict.keys())}")
print(f"弱引用字典: {list(weak_dict.keys())}")
预期输出:
text
初始状态:
普通字典: [MyClass(test_object)]
弱引用字典: [MyClass(test_object)]
删除对象引用并垃圾回收后:
普通字典: [MyClass(test_object)]
弱引用字典: []
关键区别:
引用强度:
普通字典:对键保持强引用,阻止垃圾回收
WeakKeyDictionary:对键保持弱引用,不阻止垃圾回收
内存管理:
普通字典:即使对象在其他地方不再使用,字典仍保留对象,可能导致内存泄漏
WeakKeyDictionary:当对象在其他地方不再使用时,自动移除对应条目
使用场景:
普通字典:需要长期保持对象引用时使用
WeakKeyDictionary:需要临时关联数据但不希望阻止对象回收时使用