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操作mysql数据库
Mar 05 Python
基于python list对象中嵌套元组使用sort时的排序方法
Apr 18 Python
python读取图片并修改格式与大小的方法
Jul 24 Python
利用python打开摄像头及颜色检测方法
Aug 03 Python
解决python3 Pycharm上连接数据库时报错的问题
Dec 03 Python
Python绘制并保存指定大小图像的方法
Jan 10 Python
python+pyqt5编写md5生成器
Mar 18 Python
python 3.74 运行import numpy as np 报错lib\site-packages\numpy\__init__.py
Oct 06 Python
python代码如何注释
Jun 01 Python
Python Unittest原理及基本使用方法
Nov 06 Python
pytorch简介
Nov 11 Python
常用的Python代码调试工具总结
Jun 23 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
解析使用substr截取UTF-8中文字符串出现乱码的问题
2013/06/20 PHP
ThinkPHP的I方法使用详解
2014/06/18 PHP
PHP 表单提交及处理表单数据详解及实例
2016/12/27 PHP
利用javascript查看html源文件
2006/11/08 Javascript
showModalDialog 和 showModelessDialog
2007/01/22 Javascript
js 中{},[]中括号,大括号使用详解
2011/05/12 Javascript
基于jquery的回到页面顶部按钮
2011/06/27 Javascript
深入理解JavaScript系列(27):设计模式之建造者模式详解
2015/03/03 Javascript
文字垂直滚动之javascript代码
2015/07/29 Javascript
jquery实现二级导航下拉菜单效果
2015/12/18 Javascript
jquery使用on绑定a标签无效 只能用live解决
2016/06/02 Javascript
JQuery EasyUI学习教程之datagrid 添加、修改、删除操作
2016/07/09 Javascript
微信小程序 教程之模板
2016/10/18 Javascript
Vue2学习笔记之请求数据交互vue-resource
2017/02/23 Javascript
JS实现json的序列化和反序列化功能示例
2017/06/13 Javascript
详解AngularJS2 Http服务
2017/06/26 Javascript
微信小程序滚动Tab实现左右可滑动切换
2017/08/17 Javascript
微信小程序之分享页面如何返回首页的示例
2018/03/28 Javascript
vue中$set的使用(结合在实际应用中遇到的坑)
2018/07/10 Javascript
ES6 class的应用实例分析
2019/06/27 Javascript
基于JS实现简单滑块拼图游戏
2019/10/12 Javascript
Python的Flask框架的简介和安装方法
2015/11/13 Python
Python获取CPU、内存使用率以及网络使用状态代码
2018/02/08 Python
python微信跳一跳系列之棋子定位像素遍历
2018/02/26 Python
numpy中loadtxt 的用法详解
2018/08/03 Python
Python基础之变量基本用法与进阶详解
2020/01/03 Python
Python ArgumentParse的subparser用法说明
2020/04/20 Python
春节请假条
2014/04/11 职场文书
村长反四风问题个人对照检查材料
2014/09/21 职场文书
领导干部作风整顿剖析材料
2014/10/11 职场文书
司法局群众路线教育实践活动整改措施思想汇报
2014/10/13 职场文书
给校长的建议书作文500字
2015/09/14 职场文书
严以用权专题学习研讨会发言材料
2015/11/09 职场文书
超详细Python解释器新手安装教程
2021/05/10 Python
Java基于Dijkstra算法实现校园导游程序
2022/03/17 Java/Android
Python实现提取PDF简历信息并存入Excel
2022/04/02 Python