说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gr99123(备注:教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
frozendict 是 Python 3.15(PEP 814)中新增的一个内置不可变(immutable)映射类型。它在创建之后就不允许再被修改——不能添加、删除或修改键值对。
关键特性:
frozendict 不是 dict 的子类,它直接继承自 objectfrozendict 本身也是可哈希的(即可以被当作字典的键使用)frozendict 是否相等时,顺序不参与比较(只要键值对相同即认为相等)frozendict 有三种构造方式:
frozendict(**kwargs)
frozendict(mapping, /, **kwargs)
frozendict(iterable, /, **kwargs)
参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
**kwargs |
关键字参数 | 直接以关键字形式传入键值对 |
mapping |
任意映射对象(如 dict、另一个 frozendict) |
从中复制键值对 |
iterable |
可迭代对象 | 元素为 (key, value) 二元组(或类似映射的序列) |
**kwargs(第二种/第三种) |
关键字参数 | 与 mapping/iterable 合并,后者覆盖前者 |
# 通过关键字参数创建
a = frozendict(x=1, y=2)
print(a) # frozendict({'x': 1, 'y': 2})
# 通过 dict 创建
b = frozendict({'name': 'Alice', 'age': 30})
print(b) # frozendict({'name': 'Alice', 'age': 30})
# 通过可迭代对象创建
c = frozendict()
print(c) # frozendict({'color': 'red', 'size': 'M'})
# 合并多个来源
d = frozendict({'a': 1}, b=2, c=3)
print(d) # frozendict({'a': 1, 'b': 2, 'c': 3})
a = frozendict(x=1, y=2)
# 尝试赋值 → 抛出 TypeError
a['z'] = 3
# TypeError: 'frozendict' object does not support item assignment
# 尝试删除 → 同样不行
del a['x']
# TypeError: 'frozendict' object does not support item deletion
# 尝试更新 → 也不行
a.update({'w': 4})
# TypeError: 'frozendict' object has no attribute 'update'
# 因为 frozendict 可哈希,所以可以作为 dict 的键
cache = {
frozendict(a=1, b=2): "result1",
frozendict(a=3, b=4): "result2",
}
print(cache[frozendict(a=1, b=2)]) # result1
a = frozendict(x=1, y=2)
b = frozendict(y=2, x=1) # 插入顺序不同
print(a == b) # True(键值对相同,顺序不影响相等性)
# 但迭代顺序保持创建时的插入顺序
print(list(a.items())) #
print(list(b.items())) #
a = frozendict(x=1, y=2)
b = frozendict(y=2, x=1)
print(hash(a) == hash(b)) # True(相等的 frozendict 哈希值相同)
print(hash(a)) # 一个整数
frozendict vs dict 对比| 特性 | dict |
frozendict |
|---|---|---|
| 可变性 | 可变 | 不可变 |
| 父类 | object |
object(不是 dict 子类) |
| 可哈希 | 不可哈希 | 可哈希(键值均可哈希时) |
| 支持方法 | update(), pop(), setdefault() 等 |
仅只读方法:keys(), values(), items(), get(), __contains__ 等 |
| 作为字典的键 | ❌ | ✅ |
| 插入顺序保持 | ✅(3.7+) | ✅ |
| 创建语法 | {} 字面量或 dict() |
frozendict() |
Python 3.15 中多个标准库模块已更新以接受 frozendict:
| 模块 | 支持方式 |
|---|---|
copy |
copy() / deepcopy() |
decimal |
类型转换 |
json |
序列化/反序列化 |
marshal |
序列化/反序列化 |
pickle |
序列化/反序列化 |
plistlib |
序列化(写入时) |
pprint |
Pretty-print 输出 |
xml.etree.ElementTree |
类型处理 |
此外:
eval() 和 exec() 的 _globals_ 参数现在可以接受 frozendicttype() 和 str.maketrans() 的 _dict_ 参数现在可以接受 frozendict由于 frozendict 不是 dict 的子类,传统的类型检查代码需要更新:
# 旧写法(只能检测 dict,会漏掉 frozendict)
if isinstance(obj, dict):
...
# 推荐写法 1:同时接受 dict 和 frozendict
if isinstance(obj, (dict, frozendict)):
...
# 推荐写法 2(更通用):接受所有 Mapping 类型
from collections.abc import Mapping
if isinstance(obj, Mapping):
...
需要不可变配置对象:当你的数据不应该被意外修改时,用 frozendict 替代 dict 可以作为"防御性编程"手段
需要把字典当作字典的键:比如缓存、去重等场景
线程安全读取:不可变对象天然线程安全,多个线程可以同时读取而无需加锁
函数式编程风格:在函数式编程中,数据通常不被修改,frozendict 比 dict + 手动拷贝更安全
替代 types.MappingProxyType:之前如果需要一个只读视图,常用 MappingProxyType(dict_obj),但它只是 dict 的只读包装器;frozendict 是一个独立的不可变类型,语义更清晰
frozenset 的类比理解 frozendict 最简单的方式是类比 frozenset:
| 可变类型 | 不可变类型 | 关系 |
|---|---|---|
list |
tuple |
不可变版本 |
set |
frozenset |
不可变版本 |
dict |
frozendict |
不可变版本 |
就像 frozenset 是 set 的不可变版本一样,frozendict 就是 dict 的不可变版本——只是它没有选择做 dict 的子类,而是作为一个独立的新内置类型。
frozendict 是 Python 3.15 引入的一个内置不可变字典类型,创建后不可修改、可哈希、保持插入顺序,适用于需要不可变映射语义的场景。如果你用的 Python 版本低于 3.15,可以通过第三方库 frozendict(pip install frozendict)获得类似功能,但内置版本的语义和性能经过官方优化,建议升级到 3.15+ 后直接使用。
更新时间:2026-11-01 14:16:19 标签:python 冻结字典 frozendict