当前位置: 首页 > news >正文

使用__missing__方法实现映射表多格式主键

背景介绍

在python中,我们经常使用字典类型实现映射表的功能,通过字典的主键遍历获取对应的值,从而实现从一个值映射到另一个值的功能

但是这种映射是十分硬性的,例如,假如我的映射表为{‘1’:one,‘2’:two},这是一个阿拉伯数字对应映射成英语的过程,在查找映射表的过程中,我的主键输入‘1’可以得到值one,但如果我输入的是1(即并不是加上引号的字符串类型而是数值类型),python的字典类型就会抛出主键错误的提示,因为在原字典中,‘1’是作为字符串类型的主键,1是作为整形类型的数据,两者在计算机中的储存格式是不相同的

如果我们希望得到一张映射表,既可以通过字符串类型遍历取值,也能通过对应的数值类型取值,那么应该如何实现呢?__missing__可以提供解决方案

__missing__方法

对于python中的dict类型,当我们需要通过主键获取对应的值时,k是主键,dict是字典类型,可以有dict[k]或者dict.get(k),都是调用字典类型中的__getitem__方法,遍历查找字典中对指定主键所对应的值,当没有找到主键时,则返回KeyError

另一种情况是,当__missing__方法存在时,就会调用__missing__方法中设定的操作,例如defaultdict类就是这种运行原理如何统计csv文件中对象的数量(基于pandas)-CSDN博客可以事先对不存在的字典主键赋予默认值,给在运行的过程带来方便

任务设定

为了让大家更好地理解__missing__方法,我们来简单设定一个任务,建立映射表{1:'one',2:'two',3:'three'},在建立映射的过程中,既可以使用1作为主键获取对应的值,也可以通过对应的字符串‘1’获取相应的值

代码实现

我们通过自定义类来实现,需要继承dict的类型

我们先来看看没有加__missing__方法的继承:

class UsualDict(dict):def get(self,key,default=None):try:return self[key]except KeyError:return default

其中,get()函数就是调用__getitem__方法获取主键对应的值

dd=UsualDict({1:'one',2:'two',3:'three'})
print(dd[1])输出>>one
print(dd['1'])输出>>KeyError: '1'

可见没有实现任务的要求,我们再来使用__missing__方法:

class UsualDict(dict):def __missing__(self,key):return self[int(key)]def get(self,key,default=None):try:return self[key]except KeyError:return default
print(dd['1'])输出>>one

任务好像可以完成了

但是却有一个隐藏的漏洞

print(dd[5])
Traceback (most recent call last):File "d:\py-code\fluent_pyhton\1_24.py", line 33, in <module>print(dd[5])File "d:\py-code\fluent_pyhton\1_24.py", line 25, in __missing__return self[int(key)]File "d:\py-code\fluent_pyhton\1_24.py", line 25, in __missing__return self[int(key)]File "d:\py-code\fluent_pyhton\1_24.py", line 25, in __missing__return self[int(key)][Previous line repeated 496 more times]
RecursionError: maximum recursion depth exceeded

错误提示语说递归的层级已经超过了最大的允许范围,这是为什么呢?

我们回到代码,具体看这一句

    def __missing__(self,key):return self[int(key)]

只要__getitem__方法没有得到主键的内容我们就调用__missing__方法,调用__missing__方法后的self[int(key)]又会调用__getitem__方法,那么只要key的int类型或者str类型都不存在于字典的主键中,那么两个方法之间就会无限进行递归调用,那么这个bug需要如何解决呢?

可以有以下继承方法:

class UsualDict(dict):def __missing__(self,key):if isinstance(key,int):raise KeyError(key)return self[int(key)]def get(self,key,default=None):try:return self[key]except KeyError:return default

通过isinstance方法判断key的类型是否属于int,即当__getitem__方法找不到主键调用__missing__方法时,首先判断key是否属于int,若属于int类型但又在字典主键中查找不到对应的值,则返回错误,否则,才进行key类型的转换

我们来看看是否还会出现递归的错误

dd=UsualDict({1:'one',2:'two',3:'three'})
print(dd[5])

系统进行了正确的错误输出 

Traceback (most recent call last):File "d:\py-code\fluent_pyhton\1_24.py", line 33, in <module>print(dd[5])File "d:\py-code\fluent_pyhton\1_24.py", line 24, in __missing__raise KeyError(key)
KeyError: 5

欢迎大家讨论交流~


相关文章:

  • Windows AD 组策略 通过脚本修改管理员密码:以安全方式
  • nc转tif
  • 全栈工程师
  • 【C++入门到精通】智能指针 shared_ptr循环引用 | weak_ptr 简介及C++模拟实现 [ C++入门 ]
  • 【笔记】Helm-4 最佳实践-2 values
  • 01.领域驱动设计:微服务设计为什么要选择DDD学习总结
  • 2024年【G2电站锅炉司炉】新版试题及G2电站锅炉司炉作业考试题库
  • Layui技术积累
  • Qt Quick程序的发布|Qt5中QML和Qt Quick 的更改
  • 【GitHub项目推荐--不错的 Go 学习项目】【转载】
  • ZYNQ程序固化
  • AIGC:让生成式AI成为自己的外脑(文末送书)
  • 操作无法完成,因为文件已在Windows资源管理器中打开,如何解决?以及如何将哔哩哔哩下载好的视频导出到电脑中播放?— 以vivo手机为例
  • 8.多折线图(MuliLineChart)
  • Win10 中 通过脚本弹出TF卡
  • hexo+github搭建个人博客
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • JS笔记四:作用域、变量(函数)提升
  • python docx文档转html页面
  • React组件设计模式(一)
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 产品三维模型在线预览
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 技术胖1-4季视频复习— (看视频笔记)
  • 开源地图数据可视化库——mapnik
  • 阿里云API、SDK和CLI应用实践方案
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (2022 CVPR) Unbiased Teacher v2
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转) RFS+AutoItLibrary测试web对话框
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .net与java建立WebService再互相调用
  • @SpringBootApplication 包含的三个注解及其含义
  • []FET-430SIM508 研究日志 11.3.31
  • [14]内置对象
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [autojs]逍遥模拟器和vscode对接
  • [AutoSar]BSW_Memory_Stack_004 创建一个简单NV block并调试
  • [c++] 什么是平凡类型,标准布局类型,POD类型,聚合体
  • [CISCN2019 华东北赛区]Web2
  • [CSS]CSS 字体属性
  • [delphi]保证程序只运行一个实例
  • [Django开源学习 1]django-vue-admin
  • [hdu 3652] B-number
  • [HeMIM]Cl,[AeMIM]Br,[CeEIM]Cl,([HO-PECH-MIM]Cl,[HOOC-PECH-MIM]Cl改性酚醛树脂
  • [Leetcode] 寻找数组的中心索引