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读写ini文件示例(python读写文件)
Mar 25 Python
Python模拟登录12306的方法
Dec 30 Python
Python实现的桶排序算法示例
Nov 29 Python
解读python logging模块的使用方法
Apr 17 Python
Python实现中一次读取多个值的方法
Apr 22 Python
Python XML转Json之XML2Dict的使用方法
Jan 15 Python
使用GitHub和Python实现持续部署的方法
May 09 Python
在Python中字符串、列表、元组、字典之间的相互转换
Nov 15 Python
Python如何使用turtle库绘制图形
Feb 26 Python
Python爬取365好书中小说代码实例
Feb 28 Python
PyCharm Anaconda配置PyQt5开发环境及创建项目的教程详解
Mar 24 Python
Django admin组件的使用
Oct 24 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面向对象之旅:深入理解static变量与方法
2014/01/06 PHP
jscript之Open an Excel Spreadsheet
2007/06/13 Javascript
风吟的小型JavaScirpt库 (FY.JS).
2010/03/09 Javascript
Javascript 中的 && 和 || 使用小结
2010/04/25 Javascript
javascript hashtable 修正版 下载
2010/12/30 Javascript
顶部缓冲下拉菜单导航特效的JS代码
2013/08/27 Javascript
Bootstrap前端开发案例二
2016/06/17 Javascript
微信小程序(应用号)开发新闻客户端实例
2016/10/24 Javascript
JavaScript Date 知识浅析
2017/01/29 Javascript
js实现彩色条纹滚动条效果
2017/03/15 Javascript
详解Koa中更方便简单发送响应的方式
2018/07/20 Javascript
vue项目使用axios发送请求让ajax请求头部携带cookie的方法
2018/09/26 Javascript
JavaScript使用类似break机制中断forEach循环的方法
2018/11/13 Javascript
微信小程序实现多行文字超出部分省略号显示功能
2019/10/23 Javascript
vue实现购物车选择功能
2020/01/10 Javascript
js校验开始时间和结束时间
2020/05/26 Javascript
three.js 制作动态二维码的示例代码
2020/07/31 Javascript
js实现拖拽与碰撞检测
2020/09/18 Javascript
Python使用新浪微博API发送微博的例子
2014/04/10 Python
Python 爬虫多线程详解及实例代码
2016/10/08 Python
解决Mac下首次安装pycharm无project interpreter的问题
2018/10/29 Python
用python3教你任意Html主内容提取功能
2018/11/05 Python
pycharm中使用request和Pytest进行接口测试的方法
2020/07/31 Python
Python接收手机短信的代码整理
2020/08/02 Python
深入理解css中vertical-align属性
2017/04/18 HTML / CSS
深入浅析CSS3中的Flex布局整理
2020/04/27 HTML / CSS
Prototype如何为一个Ajax添加一个参数
2015/12/06 面试题
幼师岗位求职简历的自荐信格式
2013/09/21 职场文书
会计实习期自我鉴定
2013/10/06 职场文书
招聘单位介绍信
2014/01/14 职场文书
幼儿园中班教师寄语
2014/04/03 职场文书
北京奥运会口号
2014/06/21 职场文书
公司员工离职证明书
2014/10/04 职场文书
简易离婚协议书范本2014
2014/10/15 职场文书
公司保洁员岗位职责
2015/02/13 职场文书
Python Flask请求扩展与中间件相关知识总结
2021/06/11 Python