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中的ceil()方法使用教程
May 14 Python
Python轻量级ORM框架Peewee访问sqlite数据库的方法详解
Jul 20 Python
Python基于回溯法子集树模板解决最佳作业调度问题示例
Sep 08 Python
Python利用turtle库绘制彩虹代码示例
Dec 20 Python
Python socket实现的简单通信功能示例
Aug 21 Python
解决Python plt.savefig 保存图片时一片空白的问题
Jan 10 Python
Python设计模式之代理模式实例详解
Jan 19 Python
Django中使用极验Geetest滑动验证码过程解析
Jul 31 Python
Python编程快速上手——强口令检测算法案例分析
Feb 29 Python
计算Python Numpy向量之间的欧氏距离实例
May 22 Python
Python自动登录QQ的实现示例
Aug 28 Python
Python实现灰色关联分析与结果可视化的详细代码
Mar 25 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命令行(cli)模式下报require 加载路径错误的解决方法
2015/11/23 PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
2020/03/27 PHP
slice函数的用法 之不错的应用
2006/12/29 Javascript
javascript 异常处理使用总结
2009/06/21 Javascript
一个简单的瀑布流效果(主体形式自写)
2013/05/27 Javascript
jquery 简单应用示例总结
2013/08/09 Javascript
js编码、解码函数介绍及其使用示例
2013/09/05 Javascript
JQuery中extend使用介绍
2014/03/13 Javascript
浅析javascript的间隔调用和延时调用
2014/11/12 Javascript
jquery实现侧边弹出的垂直导航
2014/12/09 Javascript
bootstrap table 服务器端分页例子分享
2015/02/10 Javascript
JavaScript实现文本框中默认显示背景图片在获得焦点后消失的方法
2015/07/01 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
2015/07/17 Javascript
包含中国城市的javascript对象实例
2015/08/03 Javascript
利用HTML5的画布Canvas实现刮刮卡效果
2015/09/06 Javascript
简介AngularJS中$http服务的用法
2016/02/06 Javascript
jQuery插件实现文件上传功能(支持拖拽)
2020/08/27 Javascript
Angular.js 实现数字转换汉字实例代码
2016/07/14 Javascript
JavaScript实现三级联动菜单效果
2017/08/16 Javascript
NodeJS设计模式总结【单例模式,适配器模式,装饰模式,观察者模式】
2017/09/06 NodeJs
vuex actions传递多参数的处理方法
2018/09/18 Javascript
typescript编写微信小程序创建项目的方法
2021/01/29 Javascript
[02:35]DOTA2超级联赛专访XB 难忘一年九冠称王
2013/06/20 DOTA
Python selenium抓取微博内容的示例代码
2018/05/17 Python
3个用于数据科学的顶级Python库
2018/09/29 Python
​如何愉快地迁移到 Python 3
2019/04/28 Python
Python常用断言函数实例汇总
2020/11/30 Python
css3实现wifi信号逐渐增强效果实例
2017/08/09 HTML / CSS
澳大利亚手表品牌:Time IV Change
2018/10/06 全球购物
小饰品店的创业计划书范文
2013/12/28 职场文书
校园餐饮创业计划书
2014/01/10 职场文书
宾馆总经理岗位职责
2014/02/14 职场文书
银行青年文明号事迹材料
2014/05/31 职场文书
文明好少年事迹材料
2014/08/19 职场文书
离婚协议书包括哪些内容
2014/10/16 职场文书
讲解MySQL增删改操作
2022/05/06 MySQL