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 相关文章推荐
mac安装scrapy并创建项目的实例讲解
Jun 13 Python
python2 与 python3 实现共存的方法
Jul 12 Python
简单了解python PEP的一些知识
Jul 13 Python
PyQt5基本控件使用详解:单选按钮、复选框、下拉框
Aug 05 Python
python爬虫selenium和phantomJs使用方法解析
Aug 08 Python
Python中zip()函数的简单用法举例
Sep 02 Python
pyinstaller 3.6版本通过pip安装失败的解决办法(推荐)
Jan 18 Python
Python是什么 Python的用处
May 26 Python
Python如何读取、写入CSV数据
Jul 28 Python
Matplotlib中%matplotlib inline如何使用
Jul 28 Python
Python Merge函数原理及用法解析
Sep 16 Python
Python 随机按键模拟2小时
Dec 30 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 最大运行时间 max_execution_time修改方法
2010/03/08 PHP
php之readdir函数用法实例
2014/11/13 PHP
PHP abstract 抽象类定义与用法示例
2018/05/29 PHP
PHP的mysqli_sqlstate()函数讲解
2019/01/23 PHP
用Javascript同时提交多个Web表单的方法
2009/12/26 Javascript
Extjs学习笔记之九 数据模型(上)
2010/01/11 Javascript
jquery控制listbox中项的移动并排序的实现代码
2010/09/28 Javascript
js下通过prototype扩展实现indexOf的代码
2010/12/08 Javascript
jquery解析xml字符串简单示例
2014/04/11 Javascript
Bootstrap table分页问题汇总
2016/05/30 Javascript
JavaScript学习笔记整理_用于模式匹配的String方法
2016/09/19 Javascript
angular2中router路由跳转navigate的使用与刷新页面问题详解
2017/05/07 Javascript
JavaScript面向对象精要(上部)
2017/09/12 Javascript
vue中添加mp3音频文件的方法
2018/03/02 Javascript
[02:41]《西雅图我们来了》2015国际邀请赛出征全记录
2015/07/23 DOTA
[00:48]完美“圣”典2016风云人物:xiao8宣传片
2016/11/30 DOTA
Python使用Pycrypto库进行RSA加密的方法详解
2016/06/06 Python
详解pandas库pd.read_excel操作读取excel文件参数整理与实例
2019/02/17 Python
从0开始的Python学习014面向对象编程(推荐)
2019/04/02 Python
Python3实现监控新型冠状病毒肺炎疫情的示例代码
2020/02/13 Python
使用python-pptx包批量修改ppt格式的实现
2020/02/14 Python
HTML5的语法变化介绍
2013/08/13 HTML / CSS
CK加拿大官网:Calvin Klein加拿大
2020/03/14 全球购物
会计系毕业个人自荐信格式
2013/09/23 职场文书
师生聚会感言
2014/01/26 职场文书
业务员的岗位职责
2014/03/15 职场文书
委托公证书范本
2014/04/03 职场文书
2014年少先队工作总结
2014/12/03 职场文书
国庆庆典邀请函
2015/02/02 职场文书
个人总结与自我评价
2015/02/14 职场文书
2015年煤矿工作总结
2015/04/28 职场文书
关于分班的感言
2015/08/04 职场文书
php 解析非标准json、非规范json
2021/04/01 PHP
用Python实现屏幕截图详解
2022/01/22 Python
《模拟人生4》推出新补丁 “婚礼奇缘”DLC终于得到修复
2022/04/03 其他游戏
解决MySQL Varchar 类型尾部空格的问题
2022/04/06 MySQL