python 不可变字典 inmutabledict的实现
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 不可变字典 inmutabledict的实现的更多相关文章
- Python基础知识---字典
现在在实习期间,好久没用Python了,今天在做Java项目时用的HashMap让我联想到了Python中的字典,就写一些Python字典的知识吧,复习复习. 字典: key --> valu ...
- python基础之字典dict和集合set
作者:tongqingliu 转载请注明出处:http://www.cnblogs.com/liutongqing/p/7043642.html python基础之字典dict和集合set 字典dic ...
- python中 字符 字典 列表之间的转换
1 字典 转 字符 定义一个字典:dict = {'name': 'python', 'age': 7}字典转字符 可以使用str强制转换 如: str(dict) 此时dict的类型就是字符型了 2 ...
- Python基础__字典、集合、运算符
之前讨论的字符串.列表.元组都是有序对象,本节则重点讨论无序对象:字典与集合.一.字典 列表是Python中的有序集合,列表中的序指的是列表中的元素与自然数集形成了一个一一对应的关系.例如L=['I' ...
- python 3.x 字典的11种方法
python 3.x 字典的11种方法2017年11月25日 01:02:11 Milton-Long 阅读数:535 标签: python python字典方法 更多个人分类: python-学习之 ...
- python的可变与不可变数据类型
<python的可变与不可变数据类型> python与C/C++不一样,它的变量使用有自己的特点,当初学python的时候,一定要记住“一切皆为对象,一切皆为对象的引用”这句话,其 ...
- Python基本序列-字典
Python 基本序列-字典 字典(dict)是"键-值 对"的无序可变序列,字典中的每个元素包含两部分,"键"和"值". 字典中的&quo ...
- Python探索记(16)——Python的可变类型与不可变类型
# @Time : 2017/7/8 17:49 # @Author : 原创作者:谷哥的小弟 # @Site : 博客地址:http://blog.csdn.net/lfdfhl # @DESC : ...
- python入门14 字典dict
字典dict是无序的key:value格式的数据序列 #coding:utf-8 #/usr/bin/python """ 2018-11-11 dinghanhua 字 ...
随机推荐
- sql函数实用——字符函数(sqlserver与mysql对比)
1.获取长度 sqlserver写法:关键字:len() 获取参数的字符数量 select Len('aksjdhh') 输出结果 7 select len('张无忌ooo') 输出 ...
- Go合集,gRPC源码分析,算法合集
年初时,朋友圈见到的最多的就是新的一年新的FlAG,年末时朋友圈最多的也是xxxx就要过去了,你的FLAG实现了吗? 这个公众号2016就已经创建了,但截至今年之前从来没发表过文章,现在想想以前很忙, ...
- POJ 1458 Common Subsequence (动态规划)
题目传送门 POJ 1458 Description A subsequence of a given sequence is the given sequence with some element ...
- ArcEngine DEM叠加影像
代码执行前: 代码执行后: 影像叠加代码: /// <summary> /// 叠加DEM /// </summary> /// <param name="pR ...
- 搭建自己的Online Judge
前言 很多人对于做题有点厌烦,但是,如果让你出题给别人做那么可能会很有意思.可是,出题只能出在一些别人的OJ上,甚至只能在自己的Word文档里出.今天我教大家一个厉害点的,叫做搭建自己的Online ...
- HttpClient工具类的使用
package com.hourui.gmall.util; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; ...
- 测试必备之Java知识(一)—— Java基础
Java基础 Java如何运行的? 开发的java源代码,通过javac编译成为平台无关的字节码文件(class),然后通过JVM的解释器将字节码解释成对应的机器码 “一次编译,到处运行”的理解 说的 ...
- 菜鸟学习Fabric源码学习 — kafka共识机制
Fabric 1.4源码分析 kafka共识机制 本文档主要介绍kafka共识机制流程.在查看文档之前可以先阅览raft共识流程以及orderer服务启动流程. 1. kafka 简介 Kafka是最 ...
- java jdk9的特性 jshell
1.进入 jshell 2.推出 /exit() 和python的解释器用法差不多
- 11、python模块的导入
前言:本文主要介绍python模块的导入,包括模块的定义.模块的作用.导入方式以及模块的搜索路径. 一.模块的定义 python模块(module),简单来说就是一个python文件,以.py结尾,文 ...