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模拟登陆Tom邮箱示例分享
Jan 13 Python
python如何实现远程控制电脑(结合微信)
Dec 21 Python
python 字典(dict)按键和值排序
Jun 28 Python
python魔法方法-自定义序列详解
Jul 21 Python
Python针对给定字符串求解所有子序列是否为回文序列的方法
Apr 21 Python
Python 实现的 Google 批量翻译功能
Aug 26 Python
Python统计分析模块statistics用法示例
Sep 06 Python
Django框架ORM数据库操作实例详解
Nov 07 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
Apr 14 Python
Python常用库Numpy进行矩阵运算详解
Jul 21 Python
详解Python中的路径问题
Sep 02 Python
Django contrib auth authenticate函数源码解析
Nov 12 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文件读写操作之文件写入代码
2011/01/13 PHP
基于PHP-FPM进程池探秘
2017/10/17 PHP
Javascript学习笔记 delete运算符
2011/09/13 Javascript
让人期待的2011年度最佳 jQuery 插件分享
2012/03/16 Javascript
基于jQuery.Validate验证库知识点的详解
2013/04/26 Javascript
时间戳转换为时间 年月日时间的JS函数
2013/08/19 Javascript
jquery 操作css样式、位置、尺寸方法汇总
2014/11/28 Javascript
javaScript中slice函数用法实例分析
2015/06/08 Javascript
jquery ajax分页插件的简单实现
2016/01/27 Javascript
JQuery Mobile 弹出式登录框的实现方法
2016/05/28 Javascript
Bootstrap基本插件学习笔记之Tooltip提示工具(18)
2016/12/08 Javascript
基于NodeJS+MongoDB+AngularJS+Bootstrap开发书店案例分析
2017/01/12 NodeJs
js获取元素下的第一级子元素的方法(推荐)
2017/03/05 Javascript
vue鼠标移入添加class样式,鼠标移出去除样式(active)实现方法
2018/08/22 Javascript
vue项目中将element-ui table表格写成组件的实现代码
2019/06/12 Javascript
在vue中使用Base64转码的案例
2020/08/07 Javascript
跟老齐学Python之再深点,更懂list
2014/09/20 Python
Python实现简单状态框架的方法
2015/03/19 Python
Python中多线程的创建及基本调用方法
2016/07/08 Python
Python在信息学竞赛中的运用及Python的基本用法(详解)
2017/08/15 Python
PyQt5每天必学之单行文本框
2018/04/19 Python
Selenium元素的常用操作方法分析
2018/08/10 Python
对web.py设置favicon.ico的方法详解
2018/12/04 Python
pycharm打开命令行或Terminal的方法
2019/01/16 Python
python列表使用实现名字管理系统
2019/01/30 Python
Python常用爬虫代码总结方便查询
2019/02/25 Python
python 多线程死锁问题的解决方案
2020/08/25 Python
python 发送get请求接口详解
2020/11/17 Python
施工资料员的岗位职责
2013/12/22 职场文书
美德好少年事迹材料
2014/01/19 职场文书
初三学习决心书
2014/03/11 职场文书
2015年教师新年寄语
2014/12/08 职场文书
2015年精神文明建设工作总结
2015/04/21 职场文书
毕业论文答辩开场白和答辩技巧
2015/05/27 职场文书
爱护环境建议书
2015/09/14 职场文书
幼师自荐信范文(2016推荐篇)
2016/01/28 职场文书