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中MYSQLdb出现乱码的解决方法
Oct 11 Python
python绘图方法实例入门
May 19 Python
TensorFlow实现RNN循环神经网络
Feb 28 Python
详解python使用pip安装第三方库(工具包)速度慢、超时、失败的解决方案
Dec 02 Python
python多线程并发让两个LED同时亮的方法
Feb 18 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
Aug 21 Python
Python Numpy中数据的常用保存与读取方法
Apr 01 Python
在keras下实现多个模型的融合方式
May 23 Python
Python使用socketServer包搭建简易服务器过程详解
Jun 12 Python
浅谈keras中的后端backend及其相关函数(K.prod,K.cast)
Jun 29 Python
Python datetime模块的使用示例
Feb 02 Python
Python爬虫基础之简单说一下scrapy的框架结构
Jun 26 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实现用户登陆简单实例
2017/04/04 PHP
laravel自定义分页效果
2017/07/23 PHP
php微信公众号开发之二级菜单
2018/10/20 PHP
javascript 实现父窗口引用弹出窗口的值的脚本
2007/08/07 Javascript
javascript replace方法与正则表达式
2008/02/19 Javascript
js 日期转换成中文格式的函数
2009/07/07 Javascript
调试Node.JS的辅助工具(NodeWatcher)
2012/01/04 Javascript
javascript动态判断html元素并执行不同的操作
2014/06/16 Javascript
JavaScript中获取样式的原生方法小结
2014/10/08 Javascript
探寻Javascript执行效率问题
2014/11/12 Javascript
jquery实现页面虚拟键盘特效
2015/08/08 Javascript
基于JS代码实现导航条弹出式悬浮菜单
2016/06/17 Javascript
MUI  Scroll插件的使用详解
2017/04/13 Javascript
javascript 正则表达式分组、断言详解
2017/04/20 Javascript
jQuery+Cookie实现切换皮肤功能【附源码下载】
2018/03/25 jQuery
Vue+Webpack完美整合富文本编辑器TinyMce的方法
2018/11/30 Javascript
浅谈Node新版本13.2.0正式支持ES Modules特性
2019/11/25 Javascript
Vue+webpack实现懒加载过程解析
2020/02/17 Javascript
浅谈TypeScript的类型保护机制
2020/02/23 Javascript
Python实现windows下模拟按键和鼠标点击的方法
2015/03/13 Python
Python实现程序的单一实例用法分析
2015/06/03 Python
Django中使用Celery的教程详解
2018/08/24 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
2019/10/12 Python
Python基于time模块表示时间常用方法
2020/06/18 Python
Expedia泰国:预订机票、酒店和旅游包(航班+酒店)
2016/09/27 全球购物
Reformation官网:美国女装品牌
2018/09/14 全球购物
英国性能汽车零件和发动机配件在线:Maxpeedingrods
2019/11/05 全球购物
Nike瑞士官网:Nike CH
2021/01/18 全球购物
请编程遍历页面上所有 TextBox 控件并给它赋值为 string.Empty
2015/12/03 面试题
高中数学教师求职信
2013/10/30 职场文书
廉洁使者实施方案
2014/03/29 职场文书
归途列车观后感
2015/06/17 职场文书
公司客户答谢酒会祝酒词
2015/08/11 职场文书
CSS3 实现的图片悬停的切换按钮
2021/04/13 HTML / CSS
CSS font-variation 可变字体的魅力(实例详解)
2022/03/03 HTML / CSS
Springboot-cli 开发脚手架,权限认证,附demo演示
2022/04/28 Java/Android