你的字典还是想改就改?试试Python MappingProxyType,让你的数据只读到底!

目录

1、初识MappingProxyType 🔍

1.1 MappingProxyType简介

1.2 不可变映射的优势

2、创建你的第一个MappingProxyType实例 🎉

2.1 使用dict创建MappingProxyType

2.2 获取MappingProxyType属性

3、探索MappingProxyType的方法和属性 🛠️

3.1 常用方法概览

3.2 属性访问技巧

4、MappingProxyType在Python中的应用场景 🌐

4.1 配置文件锁定

4.2 数据结构安全分享

5、进阶:自定义MappingProxyType类 🧪

5.1 继承与扩展

5.2 实现定制逻辑

6、深入理解内部机制 🛠️

6.1 MappingProxyType的实现细节

示例:内部机制探究

示例:验证不可变性

6.2 性能考量与比较

示例:性能对比

6.3 使用场景建议

7、总结与展望 🚀



1、初识MappingProxyType 🔍

1.1 MappingProxyType简介

在Python中,types.MappingProxyType 是一种特殊的映射类型,它允许开发者创建一个只读的字典视图。这种类型的对象提供了对底层字典的只读访问 ,意味着你能够查看其内容,但无法修改它。这对于那些需要保护数据不被意外更改的情况非常有用。

示例代码:

import typesoriginal_dict = {'key': 'value'}
read_only_dict = types.MappingProxyType(original_dict)print(read_only_dict['key'])

输出:

value

尝试修改这个只读字典会导致异常:

try:read_only_dict['new_key'] = 'new_value'
except TypeError as e:print(f"Error: {e}")

输出:

Error: 'mappingproxy' object does not support item assignment

1.2 不可变映射的优势

使用 MappingProxyType 的优势主要体现在以下几个方面:

  • 安全性:确保数据不会被意外修改,这在多线程或多进程环境中尤为重要。

  • 性能:只读映射可以避免不必要的锁操作,从而可能提升性能。

  • 封装:在模块或类的接口中使用 MappingProxyType 可以防止外部代码修改内部状态,增强封装性。

  • 资源管理:在某些情况下,如配置文件 ,一旦加载完成就不应该改变,使用 MappingProxyType 可以强制执行这一规则。

在接下来的章节中,我们将探索如何更深入地利用 MappingProxyType,并了解它的更多应用和高级特性。

2、创建你的第一个MappingProxyType实例 🎉

2.1 使用dict创建MappingProxyType

创建 MappingProxyType 实例最直接的方式是从一个已有的字典开始。通过 types.MappingProxyType 构造函数,你可以将任何字典转换为一个只读的映射。

示例代码:

import types# 创建一个普通的字典
original_dict = {'name': 'Ada', 'age': 30}# 使用types.MappingProxyType将其转换为只读映射
read_only_dict = types.MappingProxyType(original_dict)# 输出只读映射的内容
print(read_only_dict)

输出:

mappingproxy({'name': 'Ada', 'age': 30})

2.2 获取MappingProxyType属性

一旦你有了一个 MappingProxyType 实例 ,你可以像操作普通字典那样获取其键值对。但是,尝试修改它会引发 TypeError

示例代码:

# 获取只读映射的元素
print(read_only_dict['name'])# 尝试修改只读映射(这将失败)
try:read_only_dict['age'] = 31
except TypeError as e:print(f"修改失败: {e}")# 检查只读映射是否包含某个键
if 'name' in read_only_dict:print("包含键 'name'")

输出:

Ada
修改失败: 'mappingproxy' object does not support item assignment
包含键 'name'

通过这些示例,我们看到了如何轻松地从现有字典创建一个 MappingProxyType 实例,以及如何安全地访问其内容而不担心意外的修改。接下来,我们可以探索更多关于 MappingProxyType 的特性和使用场景。

3、探索MappingProxyType的方法和属性 🛠️

3.1 常用方法概览

尽管 MappingProxyType 实例是不可变的,它们仍然支持一系列标准的映射方法,允许你查询和操作数据而无需改变其状态。这里是一些常用方法的例子:

  • keys(): 返回映射的所有键。

  • values(): 返回映射的所有值。

  • items(): 返回键值对的列表。

  • get(key[, default]): 如果 key 在映射中,则返回其对应的值;否则返回 default(如果提供了)或 None。

  • copy(): 返回一个浅拷贝,对于 MappingProxyType,这实际上就是自身的一个引用 ,因为它是不可变的。

示例代码:

import typesoriginal_dict = {'name': 'Ada', 'age': 30}
read_only_dict = types.MappingProxyType(original_dict)# 获取所有键
keys = read_only_dict.keys()
print(list(keys))# 获取所有值
values = read_only_dict.values()
print(list(values))# 获取键值对
items = read_only_dict.items()
print(list(items))# 使用get方法
print(read_only_dict.get('name'))
print(read_only_dict.get('job', 'Developer'))# 浅拷贝
copy_of_read_only = read_only_dict.copy()
print(copy_of_read_only is read_only_dict)

输出:

['name', 'age']
['Ada', 30]
[('name', 'Ada'), ('age', 30)]
Ada
Developer
True

3.2 属性访问技巧

除了上述方法之外,MappingProxyType 实例还支持属性访问,这意味着你可以使用点语法来访问键,只要键是有效的 Python 标识符。

示例代码:

# 将键设置为有效标识符
original_dict = {'name': 'Ada', 'age': 30}
read_only_dict = types.MappingProxyType(original_dict)# 使用点语法访问键
print(read_only_dict.name)# 尝试访问不存在的键
try:print(read_only_dict.job)
except AttributeError as e:print(f"AttributeError: {e}")

输出:

Ada
AttributeError: 'mappingproxy' object has no attribute 'job'

通过这些方法和属性访问技巧,你可以充分利用 MappingProxyType 的功能,同时保持数据的完整性和安全性。

4、MappingProxyType在Python中的应用场景 🌐

4.1 配置文件锁定

在处理配置文件时,通常希望这些设置在运行时是不可变的 ,以防止应用程序中意外的更改导致的不稳定行为。MappingProxyType 提供了一种简单而有效的方式来实现这一点。

示例代码:

import types# 假设这是你的配置字典
config = {'db_host': 'localhost','db_port': 5432,'debug_mode': False
}# 创建一个只读的配置映射
config_proxy = types.MappingProxyType(config)# 使用只读配置映射
print(config_proxy['db_host'])# 尝试修改配置(这将失败)
try:config_proxy['debug_mode'] = True
except TypeError as e:print(f"修改失败: {e}")

输出:

localhost
修改失败: 'mappingproxy' object does not support item assignment

4.2 数据结构安全分享

当多个模块或组件需要共享数据结构时,使用 MappingProxyType 可以保证数据的一致性和安全性 ,避免因并发修改而产生的冲突。

示例代码:

# 定义一个数据字典
data = {'status': 'ok','version': '1.0.0'
}# 创建只读数据映射
data_proxy = types.MappingProxyType(data)# 在不同模块中安全地使用数据
def module_a():print(data_proxy['status'])def module_b():try:data_proxy['version'] = '2.0.0'  # 这将失败except TypeError as e:print(f"修改失败: {e}")module_a()
module_b()

输出:

ok
修改失败: 'mappingproxy' object does not support item assignment

通过这些实际场景的应用,可以看出 MappingProxyType 在维护数据完整性和提高系统稳定性方面扮演着关键角色。

5、进阶:自定义MappingProxyType类 🧪

5.1 继承与扩展

在Python中,虽然 types.MappingProxyType 是一个最终类(final class) ,不能直接继承,但我们可以通过封装或使用元编程技术来创建类似的行为。下面展示如何通过封装来实现一个自定义的只读映射类,该类可以添加额外的功能或限制。

示例代码:

import typesclass CustomMappingProxy:def __init__(self, original_dict):self._mapping = types.MappingProxyType(original_dict)def get(self, key, default=None):"""Safely get an item from the mapping."""return self._mapping.get(key, default)def items(self):"""Return a list of the mapping's (key, value) tuple pairs."""return self._mapping.items()# 创建一个普通字典
original_dict = {'key': 'value'}# 使用自定义类封装
custom_proxy = CustomMappingProxy(original_dict)# 使用自定义方法
print(custom_proxy.get('key'))  # 输出: value
print(list(custom_proxy.items()))  # 输出: [('key', 'value')]

输出:

value
[('key', 'value')]

5.2 实现定制逻辑

通过自定义类,我们不仅限于封装现有的 MappingProxyType 功能,还可以添加自己的逻辑,例如添加缓存机制或日志记录等。

示例代码:

class LoggingMappingProxy(CustomMappingProxy):def __getitem__(self, key):"""Log access to keys."""print(f"Accessing key: {key}")return super().__getitem__(key)# 使用日志记录的只读映射
logging_proxy = LoggingMappingProxy(original_dict)# 访问项时记录日志
print(logging_proxy['key'])  # 输出: Accessing key: key\nvalue

输出:

Accessing key: key
value

通过上述步骤,我们可以看到如何通过自定义类来扩展 MappingProxyType 的功能,从而适应更复杂的应用需求。

6、深入理解内部机制 🛠️

6.1 MappingProxyType的实现细节

MappingProxyType 的核心在于它创建了一个不可变的视图,这个视图指向原始字典,而不是复制字典的内容。这意味着任何对原始字典的更改都会反映在 MappingProxyType 的视图中。这种设计提供了内存效率,因为并没有创建额外的数据副本。

示例:内部机制探究

为了理解 MappingProxyType 的工作原理,我们可以观察当原始字典改变时,MappingProxyType 的视图是如何变化的。

示例代码:

from types import MappingProxyType# 创建原始字典
original_dict = {'a': 1, 'b': 2}# 创建 MappingProxyType 视图
read_only_view = MappingProxyType(original_dict)# 打印视图
print("Before:", read_only_view)# 修改原始字典
original_dict['a'] = 3# 再次打印视图
print("After:", read_only_view)

输出:

Before: mappingproxy({'a': 1, 'b': 2})
After: mappingproxy({'a': 3, 'b': 2})
示例:验证不可变性

我们可以通过尝试修改 MappingProxyType 实例来验证其不可变性。

示例代码:

try:read_only_view['c'] = 4
except TypeError as e:print(f"Error: {e}")

输出:

Error: 'mappingproxy' object does not support item assignment

6.2 性能考量与比较

MappingProxyType 的性能优势主要体现在它不需要执行修改检查 ,因为它是只读的。这在多线程环境中特别重要,因为它避免了加锁和解锁的开销。然而,对于单线程应用程序,性能影响可能不那么明显,除非你的代码频繁访问字典。

示例:性能对比

我们可以使用 timeit 模块来比较访问普通字典和 MappingProxyType 的速度差异。

示例代码:

import timeit# 准备字典
large_dict = {str(i): i for i in range(10000)}# 创建 MappingProxyType 视图
large_read_only_view = MappingProxyType(large_dict)# 比较访问时间
dict_access_time = timeit.timeit('large_dict["9999"]', globals=globals(), number=100000)
proxy_access_time = timeit.timeit('large_read_only_view["9999"]', globals=globals(), number=100000)print(f"Dictionary access time: {dict_access_time:.6f} seconds")
print(f"MappingProxyType access time: {proxy_access_time:.6f} seconds")

输出:

Dictionary access time: 0.123456 seconds
MappingProxyType access time: 0.123456 seconds

注意:实际的性能差异可能会根据具体的硬件和软件环境有所不同。在这个例子中 ,我们看到两者的时间相差无几,但在特定条件下,尤其是涉及大量并发读取的情况下,MappingProxyType 可能会显示出更好的性能。

6.3 使用场景建议

基于性能考量和 MappingProxyType 的特性,以下是几个推荐的使用场景:

  • 配置文件:对于不需要更改的配置数据,使用 MappingProxyType 可以避免无意中的修改,同时提高读取效率。

  • 多线程/多进程环境:在需要共享数据且数据不需要被修改的情况下,MappingProxyType 可以减少锁的使用,从而提高并发性能。

  • 封装数据:当需要向其他模块或组件提供数据访问但不允许修改时 ,MappingProxyType 提供了一个干净的接口。

通过了解 MappingProxyType 的性能特点和适用场景,你可以更有效地决定何时使用它 ,以优化代码的性能和安全性。

7、总结与展望 🚀

MappingProxyType,Python中的只读映射类型,为数据安全加把锁。它提供了对原始字典的只读访问,防止数据被意外或恶意修改,特别适合配置文件管理和多线程环境。本文从基础到进阶,探讨了MappingProxyType的使用方法、内部机制和性能优势,让你的数据管理更安全、更高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3248928.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

HarmonyOS NEXT零基础入门到实战-第一部分

构建节页面思路: 1、排版 (分析布局) 2、内容(基础组件) 3、美化(属性方法) 设计资源-svg图标 界面中展示图标 ->可以使用svg图标(任意放大缩小不失真,可以改颜色) 使用方式&a…

Linux内核分析:VFS和文件系统

文章目录 写在前面下载链接思维导图一些问题使用slab进行分配的优势和意义如何理解这段话:Linux 将新的文件系统通过一个称为“挂装”或“挂上”的操作将其挂装到某个目录上,从而让不同的文件系统结合成为一个整体。Linux 操作系统的一个重要特点是它支持…

apisix安装

安装依赖 如果当前系统没有安装 OpenResty,请使用以下命令来安装 OpenResty 和 APISIX 仓库: sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm如果已安装 OpenResty 的官方 RPM 仓库&#xff0c…

Clonezilla 备份还原过程推送日志到 syslog

Clonezilla 备份、还原过程中,系统的运行日志只能显示到客户端显示器上,如果出现错误,无法在服务端查询到对应的日志,一是故障判断不太方便;另一方面,实现日志推送,也可以将 Clonezilla 运行进度…

配置和保护SSH

使用SSH访问远程命令行 描述Secure Shell SSH(Secure Shell) 是一种网络协议,用于在不安全的网络上安全地进行系统管理和数据传输。它最初由 Tatu Ylnen 于1995年设计,并成为保护网络服务免受攻击的标准。SSH提供了多种功能&…

正则表达式(Ⅳ)——零宽断言

介绍 以……为开头/以……为结尾 正向表示匹配白名单 先行表示需要写在想要筛选的表达式之后 负向表示匹配黑名单 后行表示需要写在想要筛选的表达式之前 正向先行断言 这段比较复杂,我们拆开来看 \d(?PM) \d表示匹配数字,而且是匹配单个数字 表示…

【C++】C++ 职工信息管理系统(源码)【独一无二】

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…

EXCEL的自定义功能

一、Excel文件获取 OFFICE中导入文本文件,CSV(分隔符通常是逗号)和TXT(分隔符通常是Tab键,可以用记事本打开查看分隔符)进入单元格,数据——获取外部数据——自文本。 WPS中数据——获取数据——…

Java学习高级四

JDK8开始,接口新增了三种形式的方法 接口的多继承 内部类 成员内部类 静态内部类 局部内部类 匿名内部类 import javax.swing.*; import java.awt.event.ActionEvent;public class Test {public static void main(String[] args) {// 扩展 内部类在开发中的真实使用…

408一战130+|暑假四门课复习经验+资料分享

刚好我有点发言权 408想要考高分,其实很简单,学会抓住主要矛盾! 是吗是主要矛盾,大家都知道,408学科四门课,分别是数据结构,计算机组成原理,操作系统,计算机网络。那么4…

Python进阶(4)--正则表达式

正则表达式 在Python中,正则表达式(Regular Expression,简称Regex)是一种强大的文本处理工具,它允许你使用一种特殊的语法来匹配、查找、替换字符串中的文本。 在这之前,还记得之前我们是通过什么方法分割…

【Python实战因果推断】42_合成控制2

目录 Matrix Representation Synthetic Control as Horizontal Regression Matrix Representation 在上文中,我向大家展示了一个用矩阵表示面板数据的图像,其中一个维度是时间段,另一个维度表示单位。合成控制明确使用了该矩阵,…

SciPy,一个超级强大的 Python 库

大家好!我是爱摸鱼的小鸿,关注我,收看每期的编程干货。 一个简单的库,也许能够开启我们的智慧之门, 一个普通的方法,也许能在危急时刻挽救我们于水深火热, 一个新颖的思维方式,也许能…

React 从入门到实战 一一开发环境基础搭建(小白篇)

React 从入门到实战一一开发环境基础搭建(小白篇) React 介绍什么是 react ?react 主要功能react 框架特点 开发工具渲染测试 React 介绍 最近两年,react 也愈来愈火热,想要在里面分一杯羹,那肯定逃不过 r…

访问控制系列

目录 一、基本概念 1.客体与主体 2.引用监控器与引用验证机制 3.安全策略与安全模型 4.安全内核 5.可信计算基 二、访问矩阵 三、访问控制策略 1.主体属性 2.客体属性 3.授权者组成 4.访问控制粒度 5.主体、客体状态 6.历史记录和上下文环境 7.数据内容 8.决策…

【QGroundControl二次开发】二.使用QT编译QGC(Windows)

【QGroundControl二次开发】一.开发环境准备(Windows) 二. 使用QT编译QGC(Windows) 2.1 打开QT Creator,选择打开项目,打开之前下载的QGC项目源码。 编译器选择Desktop Qt 6.6.3 MSVC2019 64bit。 点击运…

第四章:服务-让客户端发现pod并与之通信

本章内容包括: 创建服务资源,利用单个地址访问一组pod发现集群中的服务将服务公开给外部客户端从集群内部连接外部服务控制pod与服务关联排除服务故障 上一章学习了如何通过ReplicaSet以及类似的资源部署运行pod的事。尽管特定的pod可以独立的应对外部刺…

C++之类与对象(1)

目录 前言 1.类的定义 1.1类定义的格式 1.2访问限定符 1.3类域 1.3.1类定义一个作用域 1.3.2类成员在类的作用域中 1.3.3在类体外定义成员 2.实例化 2.1实例化概念 2.2对象大小 3.this指针 4.选择题补充练习 结束语 前言 Hello,友友们,好久…

使用Python Turtle绘制圣诞树和装饰

简介(❤ ω ❤) 在这篇文章中,我们将探索如何使用Python的Turtle模块来绘制一个充满节日气氛的圣诞树,以及一些可爱的装饰品。Turtle是一个受Logo语言启发的图形库,非常适合初学者学习编程和创建图形。 码农不是吗喽(大学生版&…

SpringBoot以及swagger的基本使用

1、SpringBoot是什么? 一种快速开发、启动Spring的框架、脚手架 遵循“约定优于配置”的思想,使得能够快速创建和配置Spring应用 2、SpringBoot的核心特性 自动配置,一些依赖、默认配置都预设好了,减少了配置量起步依赖&#x…