本文主要介绍“如何在Python中使用missing()函数”。在日常操作中,相信很多人对于Python中的missing()函数如何使用都有疑问。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮你解答“Python中缺失的()函数怎么用”的疑惑!接下来,请和边肖一起学习!
本文的主要关注点是:
missing是谁()?
missing有什么特别之处?擅长“化人为人”的魔术?
(3)missing()真的是上述发现的例外吗?如果有,为什么会有这样的特例?
00-1010从普通字典中取值时,可能会出现键不存在的情况:
dd={ ' name ' : ' PythonCat ' }
获得('年龄')#结果:无
Dd.get('年龄',18)#结果:18
Dd['age']#错误键错误
DD。_ _ getitem _ _(“age”)#相当于DD[“age”]
对于get()方法,它有一个返回值,当键不存在时,可以传入第二个参数作为返回内容,所以是可以接受的。但是,另外两种写法会给一个错误。
为了解决后两种写作方法的问题,可以使用missing()的魔术方法。
现在,假设我们有一个诉求:从字典中取一个键对应的值,如果有值就返回值,没有值就插入键,给它一个默认值(比如空列表)。
如果使用原生dict,实现起来并不容易。但是,Python提供了非常有用的扩展类集合。
如图所示,当获取不存在的密钥时,不会再次报告密钥错误,而是默认存储在字典中。
为什么defaultdict可以这样做?
原因是defaultdict在继承了内置类型dict之后,还定义了一个missing()方法。当getitem接受一个不存在的值时,它将调用作为参数传入的工厂函数(上面的例子是调用list()来创建一个空列表)。
作为最典型的例子,defaultdict在文档注释中写道:
简而言之,missing()的主要功能是在缺少密钥时由getitem调用,以避免密钥错误。
另一个典型的使用示例是集合。计数器,它也是dict的一个子类。当获取尚未计数的密钥时,它返回计数0:
00-1010从上面我们可以看到,当missing()得不到值时,就会调用getitem()。但是,我偶然发现了一个细节:getitem()得不到值的时候,不一定会叫missing()。
。
这是因为它并非内置类型的必要属性,并没有在字典基类中被预先定义。
如果你直接从 dict 类型中取该属性值,会报属性不存在:AttributeError: type object 'object' has no attribute '__missing__'
。
使用 dir() 查看,发现确实不存在该属性:
如果从 dict 的父类即 object 中查看,也会发现同样的结果。
这是怎么回事呢?为什么在 dict 和 object 中都没有missing属性呢?
然而,查阅最新的官方文档,object 中分明包含这个属性:
出处:3. Data model — Python 3.10.1 documentationmissing#object.missing
也就是说,理论上 object 类中会预定义missing,其文档证明了这一点,然而实际上它并没有被定义!文档与现实出现了偏差!
如此一来,当 dict 的子类(例如 defaultdict 和 Counter)在定义missing 时,这个魔术方法事实上只属于该子类,也就是说,它是一个诞生于子类中的魔术方法!
据此,我有一个不成熟的猜想:getitem()会判断当前对象是否是 dict 的子类,且是否拥有missing(),然后才会去调用它(如果父类中也有该方法,则不会先作判断,而是直接就调用了)。
我在交流群里说出了这个猜想,有同学很快在 CPython 源码中找到验证:
而这就有意思了,在内置类型的子类上才存在的魔术方法,纵观整个 Python 世界,恐怕再难以找出第二例。
我突然有一个联想:这神出鬼没的missing(),就像是一个擅长玩“大变活人”的魔术师,先让观众在外面透过玻璃看到他(即官方文档),然而揭开门时,他并不在里面(即内置类型),再变换一下道具,他又完好无损就出现了(即 dict 的子类)。
3、被施魔法的missing()
missing() 的神奇之处,除了它本身会变“魔术”之外,它还需要一股强大的“魔法”才能驱动。
我发现原生的魔术方法间相互独立,它们在 C 语言界面可能有相同的核心逻辑,但是在 Python 语言界面,却并不存在着调用关系:
魔术方法的这种“老死不相往来”的表现,违背了一般的代码复用原则,也是导致内置类型的子类会出现某些奇怪表现的原因。
官方 Python 宁肯提供新的 UserString、UserList、UserDict 子类,也不愿意复用魔术方法,唯一合理的解释似乎是令魔术方法相互调用的代价太大。
但是,对于特例missing(),Python 却不得不妥协,不得不付出这种代价!
missing() 是魔术方法的“二等公民”,它没有独立的调用入口,只能被动地由 getitem() 调用,即missing() 依赖于getitem()。
不同于那些“一等公民”,例如 init()、enter()、len()、eq() 等等,它们要么是在对象生命周期或执行过程的某个节点被触发,要么由某个内置函数或操作符触发,这些都是相对独立的事件,无所依赖。
missing() 依赖于getitem(),才能实现方法调用;而 getitem() 也要依赖 missing(),才能实现完整功能。
为了实现这一点,getitem()在解释器代码中开了个后门,从 C 语言界面折返回 Python 界面,去调用那个名为“missing”的特定方法。
而这就是真正的“魔法”了,目前为止,missing()似乎是唯一一个享受了此等待遇的魔术方法!
到此,关于“Python中missing()函数怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/156067.html