python如何实现不可变字典inmutabledict


Posted in Python onJanuary 08, 2020

这篇文章主要介绍了python如何实现不可变字典inmutabledict,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

关于在python中如何实现不可变字典的方法。早在pep416中,就建议python官方实现inmutabledict,但是官方否认了。理由主要是

  • 根据Raymond Hettinger的说法,使用frozendict很愚蠢。 那些使用它的人倾向于仅将它用作提示,例如声明全局或类级别的“常量”:它们实际上不是永久不变的,因为任何人仍然可以指定名称。
  • There are existing idioms for avoiding mutable default values.

所以,这个提议就被否决了。但是我们依旧可以自己实现一个inmutabledict。inmutable主要的特点是

  • dict内的值只能在初始化的时候指定
  • 在运行期间,不能添加删除新增dict内部的值

结合starkoverflow上面的回答

我们可以通过如下几种魔改的方式实现python的inmutabledict

几种变通的方案

1. 最原始的方法,修改setitem魔术方法

在python中,d["foo"]=bar,将foo和bar作为参数,调用的是python的模式方法__setitem__。函数原型为def __setitem__(self, key, value):。所以,我们可以继承dict类,实现自己的__setitem__。在修改值的时候,抛出TypeError。不就是可以达到无法修改字典的值的目的了嘛。代码如下

class myDict(dict):
  def __setitem__(self, key, value):
    raise TypeError("inmutabledict can not be modifyed value")

d = myDict({1:2,3:4})
d[1]=4

运行则会提示

raise TypeError("inmutabledict can not be modifyed value")
TypeError: inmutabledict can not be modifyed value

Process finished with exit code 1

很好,完美的完成了任务。这种方法应用最为广泛,在werkzeug框架中的ImmutableDict等,就是通过修改魔术方法来实现的不可变字典类型。

但是在pep0416中,还提到了几种其他方法,PyDictProxy_New等。下面来试一下

2. pythonapi.PyDictProxy_New

在官方介绍capi的PyDictProxy_New中,使用代理模式,代理使用字典。并且拦截了字典的修改请求。介绍如下

PyObject* PyDictProxy_New(PyObject *mapping)¶
Return value: New reference.
Return a types.MappingProxyType object for a mapping which enforces read-only behavior. This is normally used to create a view to prevent modification of the dictionary for non-dynamic class types.

意思就是你传入个dict,这个函数返回一个dict(其实是types.MappingProxyType),然后这个返回的dict就不可以修改啦。是不是很简单,代码实现如下

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from ctypes import pythonapi, py_object

PyDictProxy_New = pythonapi.PyDictProxy_New
PyDictProxy_New.argtypes = (py_object,)
PyDictProxy_New.restype = py_object

def make_dictproxy(obj):
  assert isinstance(obj, dict)
  return pythonapi.PyDictProxy_New(obj)
a={'a': 'b', 'c': 'd'}
d = make_dictproxy(a)

这是如果修改的话,则会提示TypeError: 'mappingproxy' object does not support item assignment。同样达到了要求。这种方法的弊端主要在于依赖特定的平台,只能适用于cpython。而上面那种则适用于所有平台,cpython,pypy等。

3 .class types.MappingProxyType(mapping)
这种方法其实于PyDictProxy_New一样,只不过在py3.3中才实现。
代码如下

from types import MappingProxyType
def make_dictproxy(obj):
  assert isinstance(obj, dict)
  return MappingProxyType(obj)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python版本的读写锁操作方法
Apr 25 Python
基于python的多进程共享变量正确打开方式
Apr 28 Python
python数据类型之间怎么转换技巧分享
Aug 20 Python
如何利用Python开发一个简单的猜数字游戏
Sep 22 Python
在keras 中获取张量 tensor 的维度大小实例
Jun 10 Python
Python enumerate() 函数如何实现索引功能
Jun 29 Python
python raise的基本使用
Sep 10 Python
python实现canny边缘检测
Sep 14 Python
python中字典增加和删除使用方法
Sep 30 Python
如何使用Pytorch搭建模型
Oct 26 Python
Python Django模型详解
Oct 05 Python
Python通过loop.run_in_executor执行同步代码 同步变为异步
Apr 11 Python
PyQt5 closeEvent关闭事件退出提示框原理解析
Jan 08 #Python
python从内存地址上加载python对象过程详解
Jan 08 #Python
PyCharm第一次安装及使用教程
Jan 08 #Python
Python namedtuple命名元组实现过程解析
Jan 08 #Python
Pytorch基本变量类型FloatTensor与Variable用法
Jan 08 #Python
python pycharm最新版本激活码(永久有效)附python安装教程
Sep 18 #Python
pytorch 中pad函数toch.nn.functional.pad()的用法
Jan 08 #Python
You might like
PHP笔记之:基于面向对象设计的详解
2013/05/14 PHP
php遍历目录输出目录及其下的所有文件示例
2014/01/27 PHP
从零开始学YII2框架(二)通过 Composer 安装扩展插件
2014/08/20 PHP
PHP中strcmp()和strcasecmp()函数字符串比较用法分析
2016/01/07 PHP
PHP HTTP 认证实例详解
2016/11/03 PHP
用js实现上传图片前的预览(TX的面试题)
2007/08/14 Javascript
菜鸟javascript基础资料整理2
2010/12/06 Javascript
防止文件缓存的js代码
2013/01/10 Javascript
Javascript算符的优先级介绍
2013/03/20 Javascript
ie中js创建checkbox默认选中问题探讨
2013/10/21 Javascript
JavaScript面向对象程序设计创建对象的方法分析
2018/08/13 Javascript
对angularJs中自定义指令replace的属性详解
2018/10/09 Javascript
基于脚手架创建Vue项目实现步骤详解
2020/08/03 Javascript
[55:02]2014 DOTA2国际邀请赛中国区预选赛 HGT VS Orenda
2014/05/21 DOTA
[02:12]探秘2016国际邀请赛中国区预选赛选手房间
2016/06/25 DOTA
[47:45]DOTA2-DPC中国联赛 正赛 Phoenix vs Dragon BO3 第一场 2月26日
2021/03/11 DOTA
python动态监控日志内容的示例
2014/02/16 Python
python利用paramiko连接远程服务器执行命令的方法
2017/10/16 Python
对Python3 * 和 ** 运算符详解
2019/02/16 Python
pytorch打印网络结构的实例
2019/08/19 Python
Python实现图片裁剪的两种方式(Pillow和OpenCV)
2019/10/30 Python
用python求一重积分和二重积分的例子
2019/12/06 Python
PyTorch笔记之scatter()函数的使用
2020/02/12 Python
关于python3.9安装wordcloud出错的问题及解决办法
2020/11/02 Python
分享一枚pycharm激活码适用所有pycharm版本我的pycharm2020.2.3激活成功
2020/11/20 Python
python SOCKET编程基础入门
2021/02/27 Python
HTML5 Canvas中使用用路径描画圆弧
2015/01/01 HTML / CSS
阿联酋优惠券服务:Living Kool
2019/12/12 全球购物
英国最好的包装供应商:Priory Direct
2019/12/17 全球购物
县优秀教师事迹材料
2014/01/31 职场文书
人力资源主管的岗位职责
2014/03/15 职场文书
机械设计专业大学生职业生涯规划书范文
2014/09/13 职场文书
幼儿教师小班个人总结
2015/02/05 职场文书
投资合作意向书范本
2015/05/08 职场文书
sqlserver2017共享功能目录路径不可改的解决方法
2021/04/16 SQL Server
手把手教你用SpringBoot将文件打包成zip存放或导出
2021/06/11 Java/Android