玩转python:通俗易懂掌握高级数据结构-collections模块之UserDict

devtools/2025/3/18 22:57:24/
引言

UserDict是Python中collections模块提供的一个强大工具,它是dict的封装类,允许用户自定义字典的行为。通过继承UserDict,开发者可以轻松扩展字典的功能,实现自定义的字典逻辑。本文将详细介绍UserDict的关键用法和特性,并通过10个丰富的案例帮助读者掌握其应用。


关键用法和特性表格
特性/方法描述
自定义字典行为继承UserDict可以自定义字典的行为,如添加、删除、查找等。
封装原始字典UserDict内部封装了一个字典对象,可以通过data属性访问。
初始化使用UserDict(initialdata)创建,支持传入初始字典。
data返回内部封装的字典对象。
支持所有字典操作支持所有字典操作,如键值访问、更新、删除等。
扩展功能可以通过重写方法实现自定义功能,如验证键值、记录操作日志等。

1. UserDict的概念

UserDictcollections模块中的一个类,它是dict的封装类。它的主要特点是:

  • 自定义字典行为:通过继承UserDict,可以自定义字典的行为。
  • 封装原始字典UserDict内部封装了一个字典对象,可以通过data属性访问。
  • 高效性能:与普通字典相比,UserDict在自定义功能的同时性能依然高效。

2. UserDict的用法

2.1 创建UserDict
python">from collections import UserDict# 创建一个空的UserDict
ud = UserDict()
print(ud)  # 输出: {}# 从字典创建UserDict
ud = UserDict({'a': 1, 'b': 2})
print(ud)  # 输出: {'a': 1, 'b': 2}
2.2 访问键值对
python"># 访问键值对
print(ud['a'])  # 输出: 1
print(ud['b'])  # 输出: 2
2.3 修改键值对
python"># 修改键值对
ud['a'] = 10
print(ud)  # 输出: {'a': 10, 'b': 2}

3. UserDict的常见方法

3.1 data:访问内部字典
python"># 访问内部字典
print(ud.data)  # 输出: {'a': 10, 'b': 2}
3.2 自定义字典行为
python"># 自定义字典行为
class MyDict(UserDict):def __setitem__(self, key, value):if not isinstance(key, str):raise TypeError("Key must be a string")super().__setitem__(key, value)md = MyDict({'a': 1, 'b': 2})
md['c'] = 3  # 正常
md[1] = 'a'  # 报错: TypeError

4. UserDict的10个应用案例

案例1:验证键类型

场景:自定义一个字典,确保所有键都是字符串。

python">class StrKeyDict(UserDict):def __setitem__(self, key, value):if not isinstance(key, str):raise TypeError("Key must be a string")super().__setitem__(key, value)# 使用StrKeyDict
skd = StrKeyDict({'a': 1, 'b': 2})
skd['c'] = 3  # 正常
skd[1] = 'a'  # 报错: TypeError
案例2:记录操作日志

场景:自定义一个字典,记录所有添加和删除操作。

python">class LoggingDict(UserDict):def __setitem__(self, key, value):print(f"添加键值对: {key} -> {value}")super().__setitem__(key, value)def __delitem__(self, key):print(f"删除键: {key}")super().__delitem__(key)# 使用LoggingDict
ld = LoggingDict({'a': 1, 'b': 2})
ld['c'] = 3  # 输出: 添加键值对: c -> 3
del ld['a']  # 输出: 删除键: a
案例3:限制字典大小

场景:自定义一个字典,限制其最大大小。

python">class LimitedDict(UserDict):def __init__(self, maxsize, *args, **kwargs):super().__init__(*args, **kwargs)self.maxsize = maxsizedef __setitem__(self, key, value):if len(self) >= self.maxsize:self.popitem()super().__setitem__(key, value)# 使用LimitedDict
ld = LimitedDict(2, {'a': 1, 'b': 2})
ld['c'] = 3  # 字典变为 {'b': 2, 'c': 3}
案例4:实现默认值字典

场景:自定义一个字典,访问不存在的键时返回默认值。

python">class DefaultValueDict(UserDict):def __init__(self, default_value, *args, **kwargs):super().__init__(*args, **kwargs)self.default_value = default_valuedef __missing__(self, key):return self.default_value# 使用DefaultValueDict
dvd = DefaultValueDict(0, {'a': 1, 'b': 2})
print(dvd['a'])  # 输出: 1
print(dvd['c'])  # 输出: 0(默认值)
案例5:实现大小写不敏感字典

场景:自定义一个字典,键的大小写不敏感。

python">class CaseInsensitiveDict(UserDict):def __setitem__(self, key, value):super().__setitem__(key.lower(), value)def __getitem__(self, key):return super().__getitem__(key.lower())# 使用CaseInsensitiveDict
cid = CaseInsensitiveDict({'a': 1, 'B': 2})
print(cid['A'])  # 输出: 1
print(cid['b'])  # 输出: 2
案例6:实现只读字典

场景:自定义一个字典,禁止修改和删除操作。

python">class ReadOnlyDict(UserDict):def __setitem__(self, key, value):raise TypeError("字典是只读的,不能修改")def __delitem__(self, key):raise TypeError("字典是只读的,不能删除")# 使用ReadOnlyDict
rod = ReadOnlyDict({'a': 1, 'b': 2})
print(rod['a'])  # 输出: 1
rod['c'] = 3  # 报错: TypeError
案例7:实现计数器字典

场景:自定义一个字典,统计每个键的访问次数。

python">class CountingDict(UserDict):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.count = {}def __getitem__(self, key):self.count[key] = self.count.get(key, 0) + 1return super().__getitem__(key)# 使用CountingDict
cd = CountingDict({'a': 1, 'b': 2})
print(cd['a'])  # 输出: 1
print(cd['a'])  # 输出: 1
print(cd.count)  # 输出: {'a': 2}
案例8:实现缓存字典

场景:自定义一个字典,缓存计算结果。

python">class CachingDict(UserDict):def __init__(self, func, *args, **kwargs):super().__init__(*args, **kwargs)self.func = funcdef __getitem__(self, key):if key not in self:self[key] = self.func(key)return super().__getitem__(key)# 使用CachingDict
def expensive_computation(key):return key.upper()cd = CachingDict(expensive_computation)
print(cd['a'])  # 输出: A
print(cd['a'])  # 输出: A(从缓存中获取)
案例9:实现优先级字典

场景:自定义一个字典,按优先级插入键值对。

python">class PriorityDict(UserDict):def insert_priority(self, key, value, priority):for k, (p, _) in self.items():if priority > p:self[key] = (priority, value)returnself[key] = (priority, value)# 使用PriorityDict
pd = PriorityDict()
pd.insert_priority('task1', 'low', 1)
pd.insert_priority('task2', 'high', 3)
pd.insert_priority('task3', 'medium', 2)
print(pd)  # 输出: {'task2': (3, 'high'), 'task3': (2, 'medium'), 'task1': (1, 'low')}
案例10:实现去重字典

场景:自定义一个字典,确保值不重复。

python">class UniqueValueDict(UserDict):def __setitem__(self, key, value):if value in self.values():raise ValueError("值已存在")super().__setitem__(key, value)# 使用UniqueValueDict
uvd = UniqueValueDict({'a': 1, 'b': 2})
uvd['c'] = 3  # 正常
uvd['d'] = 2  # 报错: ValueError

总结

UserDict是Python中一个非常实用的工具,能够帮助开发者轻松扩展字典的功能。通过本文的详细讲解和10个实际案例,大家可以快速掌握UserDict的使用方法,并在实际项目中灵活应用。无论是验证键类型、记录操作日志,还是实现缓存和去重字典,UserDict都能轻松应对!


http://www.ppmy.cn/devtools/168173.html

相关文章

MySQL -- 复合查询

数据库的查询是数据库使用中比较重要的环节,前面的基础查询比较简单,不做介绍,可自行查阅。本文主要介绍复合查询,并结合用例进行讲解。 本文的用例依据Soctt模式的经典测试表,可以自行下载,也可以自己创建…

解释 TypeScript 中的枚举(enum),如何使用枚举定义一组常量?

枚举(Enum)​ 是 TypeScript 中用于定义一组具名常量的核心类型,通过语义化的命名提升代码可读性,同时利用类型检查减少低级错误。 以下从定义方式、使用建议、注意事项三方面深入解析。 一、枚举的定义方式 1. 数字枚举 特性&…

goweb中文件上传和文件下载

文件上传 文件上传:客户端把上传文件转换为二进制流后发送给服务器,服务器对二进制流进行解析HTML表单(form)enctype(Encode Type)属性控制表单在提交数据到服务器时数据的编码类型 enctype“application/x-www-form-urlencoded” 默认值,表单数据会被编码为名称/值形式。oenc…

机器学习之激活函数

什么是激活函数 激活函数是神经网络的关键组件,作用于神经元输出。神经元汇总输入并计算净输入值,激活函数将其非线性变换,生成神经元最终输出,该输出作为后续神经元输入在网络中传播。 为什么需要激活函数 引入非线性 无激活…

websocket学习手册及python实现简单的聊天室

概述 WebSocket 是一种网络通信协议,允许在单个 TCP 连接上进行全双工通信。它最核心的优势就在于实现了持久连接,实现了实时的数据传输。HTTP 协议有一个很大的缺点,通信只能由客户端发起,服务器返回响应后连接就会关闭&#xf…

Hyperlane:Rust 生态中的轻量级高性能 HTTP 服务器库,助力现代 Web 开发

Hyperlane:Rust 生态中的轻量级高性能 HTTP 服务器库,助力现代 Web 开发 在 Rust 生态系统中,Hyperlane 是一个备受关注的 HTTP 服务器库,以其轻量级、高性能和易用性脱颖而出。无论你是想快速构建一个高效的 Web 服务&#xff0…

[原创](Modern C++)现代C++的关键性概念: array<>比内置数组更安全

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、C …

搭建阿里云专有网络VPC

目录 一、概述 二、专有网络vpc 2.1 vpc基本信息 2.2 vpc资源管理 2.3 vpc网段管理 三、交换机 四、NAT网关 4.1 绑定弹性公网IP 4.2 NAT网关信息 4.3 绑定的弹性公网IP 4.4 DNAT 4.5 SNAT 五、弹性公网IP 六、访问控制ACL(绑定交换机) 6…