返回顶部
首页 > 资讯 > 后端开发 > Python >Python魔法函数missing怎么使用
  • 219
分享到

Python魔法函数missing怎么使用

2023-06-29 11:06:50 219人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要介绍了python魔法函数missing怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python魔法函数missing怎么使用文章都会有所收获,下面我们一起来看看吧。1、有点价值的__mi

这篇文章主要介绍了python魔法函数missing怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python魔法函数missing怎么使用文章都会有所收获,下面我们一起来看看吧。

Python魔法函数missing怎么使用

1、有点价值的__missing__()

从普通的字典中取值时,可能会出现 key 不存在的情况:

dd = {'name':'PythonCat'}dd.get('age')        # 结果:Nonedd.get('age', 18)    # 结果:18dd['age']            # 报错 KeyErrordd.__getitem__('age')  # 等同于 dd['age']

Python魔法函数missing怎么使用

对于 get() 方法,它是有返回值的,而且可以传入第二个参数,作为 key 不存在时的返回内容,因此还可以接受。但是,另外两种写法都会报错。

为了解决后两种写法的问题,就可以用到 __missing__() 魔术方法。

现在,假设我们有一个这样的诉求:从字典中取某个 key 对应的 value,如果有值则返回值,如果没有值则插入 key,并且给它一个默认值(例如一个空列表)。

如果用原生的 dict,并不太好实现,但是,Python 提供了一个非常好用的扩展类collections.defaultdict

Python魔法函数missing怎么使用

如图所示,当取不存在的 key 时,没有再报 KeyError,而是默认存入到字典中。

为什么 defaultdict 可以做到这一点呢?

原因是 defaultdict 在继承了内置类型 dict 之后,还定义了一个 __missing__() 方法,当 __getitem__取不存在的值时,它就会调用入参中传入的工厂函数(上例是调用 list(),创建空列表)。

作为最典型的示例,defaultdict 在文档注释中写到:

Python魔法函数missing怎么使用

简而言之,__missing__()的主要作用就是由__getitem__在缺失 key 时调用,从而避免出现 KeyError。

另外一个典型的使用例子是collections.Counter,它也是 dict 的子类,在取未被统计的 key 时,返回计数 0:

Python魔法函数missing怎么使用

2、神出鬼没的__missing__()

由上可知,__missing__()在__getitem__()取不到值时会被调用,但是,我不经意间还发现了一个细节:__getitem__()在取不到值时,并不一定会调用__missing__()。

这是因为它并非内置类型的必要属性,并没有在字典基类中被预先定义。

如果你直接从 dict 类型中取该属性值,会报属性不存在:AttributeError: type object 'object' has no attribute '__missing__'

使用 dir() 查看,发现确实不存在该属性:

Python魔法函数missing怎么使用

如果从 dict 的父类即 object 中查看,也会发现同样的结果。

这是怎么回事呢?为什么在 dict 和 object 中都没有__missing__属性呢?

然而,查阅最新的官方文档,object 中分明包含这个属性:

Python魔法函数missing怎么使用

出处:https://docs.python.org/3/reference/datamodel.html?highlight=__missing__#object.__missing__

也就是说,理论上 object 类中会预定义__missing__,其文档证明了这一点,然而实际上它并没有被定义!文档与现实出现了偏差!

如此一来,当 dict 的子类(例如 defaultdict 和 Counter)在定义__missing__ 时,这个魔术方法事实上只属于该子类,也就是说,它是一个诞生于子类中的魔术方法!

据此,我有一个不成熟的猜想:__getitem__()会判断当前对象是否是 dict 的子类,且是否拥有__missing__(),然后才会去调用它(如果父类中也有该方法,则不会先作判断,而是直接就调用了)。

我在交流群里说出了这个猜想,有同学很快在 CPython 源码中找到验证:

Python魔法函数missing怎么使用

而这就有意思了,在内置类型的子类上才存在的魔术方法,纵观整个 Python 世界,恐怕再难以找出第二例。

我突然有一个联想:这神出鬼没的__missing__(),就像是一个擅长玩“大变活人”的魔术师,先让观众在外面透过玻璃看到他(即官方文档),然而揭开门时,他并不在里面(即内置类型),再变换一下道具,他又完好无损就出现了(即 dict 的子类)。

3、被施魔法的__missing__()

__missing__() 的神奇之处,除了它本身会变“魔术”之外,它还需要一股强大的“魔法”才能驱动。

在上篇文章中,我发现原生的魔术方法间相互独立,它们在 C 语言界面可能有相同的核心逻辑,但是在 Python 语言界面,却并不存在着调用关系:

Python魔法函数missing怎么使用

魔术方法的这种“老死不相往来”的表现,违背了一般的代码复用原则,也是导致内置类型的子类会出现某些奇怪表现的原因。

官方 Python 宁肯提供新的 UserString、UserList、UserDict 子类,也不愿意复用魔术方法,唯一合理的解释似乎是令魔术方法相互调用的代价太大。

但是,对于特例__missing__(),Python 却不得不妥协,不得不付出这种代价!

__missing__() 是魔术方法的“二等公民”,它没有独立的调用入口,只能被动地由 __getitem__() 调用,即__missing__() 依赖于__getitem__()。

不同于那些“一等公民”,例如 __init__()、__enter__()、__len__()、__eq__() 等等,它们要么是在对象生命周期或执行过程的某个节点被触发,要么由某个内置函数或操作符触发,这些都是相对独立的事件,无所依赖。

__missing__() 依赖于__getitem__(),才能实现方法调用;而 __getitem__() 也要依赖 __missing__(),才能实现完整功能。

为了实现这一点,__getitem__()在解释器代码中开了个后门,从 C 语言界面折返回 Python 界面,去调用那个名为“__missing__”的特定方法。

Python魔法函数missing怎么使用

而这就是真正的“魔法”了,目前为止,__missing__()似乎是唯一一个享受了此等待遇的魔术方法!

4、小结

Python 的字典提供了两种取值的内置方法,即__getitem__() 和 get(),当取值不存在时,它们的处理策略是不一样的:前者会报错KeyError,而后者会返回 None。

为什么 Python 要提供两个不同的方法呢?或者应该问,为什么 Python 要令这两个方法做出不一样的处理呢?

这可能有一个很复杂(也可能是很简单)的解释,本文暂不深究了。

不过有一点是可以确定的:即原生 dict 类型简单粗暴地抛KeyError的做法有所不足。

为了让字典类型有更强大的表现(或者说让__getitem__()作出 get() 那样的表现),Python 让字典的子类可以定义__missing__(),供__getitem__()查找调用。

本文梳理了__missing__()的实现原理,从而揭示出它并非是一个毫不起眼的存在,恰恰相反,它是唯一一个打破了魔术方法间壁垒,支持被其它魔术方法调用的特例!

Python 为了维持魔术方法的独立性,不惜煞费苦心地引入了 UserString、UserList、UserDict 这些派生类,但是对于 __missing__(),它却选择了妥协。

关于“Python魔法函数missing怎么使用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Python魔法函数missing怎么使用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网Python频道。

--结束END--

本文标题: Python魔法函数missing怎么使用

本文链接: https://lsjlt.com/news/324563.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python魔法函数missing怎么使用
    这篇文章主要介绍了Python魔法函数missing怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python魔法函数missing怎么使用文章都会有所收获,下面我们一起来看看吧。1、有点价值的__mi...
    99+
    2023-06-29
  • Python中missing()函数怎么使用
    这篇文章主要介绍“Python中missing()函数怎么使用”,在日常操作中,相信很多人在Python中missing()函数怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python中missin...
    99+
    2023-06-22
  • python魔法函数是什么
    魔法函数是python中的一种高级语法,魔法函数可以在类中自定义函数,并绑定到类;使用魔法函数为类增加一些额外功能,也可以增强对象的类型。常见的魔法函数有__init__()、__str__()、__new__()、__unicode__(...
    99+
    2024-04-02
  • python魔法方法 __ slots __怎么使用
    这篇文章主要讲解了“python魔法方法 __ slots __怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python魔法方法 __&nb...
    99+
    2023-07-05
  • 常用的python魔法函数有哪些
    在Python中,魔法函数(或特殊方法)是具有双下划线开始和结束的特殊函数,用于定义类的行为和操作。以下是一些常用的Python魔法...
    99+
    2023-10-25
    python
  • python中有什么集合魔法函数
    这篇文章主要介绍了python中有什么集合魔法函数,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、说明_len_: 调用len()方法时,就是调用对象内的_len_()方法...
    99+
    2023-06-15
  • python里的魔法函数有哪些
    python中的魔法函数有以下几种__init__()函数__init__()函数的作用:__init__()函数的作用是常用于初始化实例对象,每次构造一个实例对象时,都会调用该类的初始化函数。__init__()函数使用方法:>>> cl...
    99+
    2024-04-02
  • Python中最神秘的魔法函数是什么
    这篇文章主要介绍“Python中最神秘的魔法函数是什么”,在日常操作中,相信很多人在Python中最神秘的魔法函数是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python中最神秘的魔法函数是什么”的疑...
    99+
    2023-06-22
  • 如何使用 PHP 魔术函数?
    php 魔术函数是自动调用的特殊函数,可用于在创建或访问类属性和方法时执行自定义操作。这些函数包括:__construct()、__destruct()、__get()、__set()、...
    99+
    2024-04-17
    php 魔术函数
  • Python中的魔法函数总结整理
    基本魔法方法 功能 __new__(cls[, ...]) 1. new 是在一个对象实例化的时候所调用的第一个方法 2. 它的第一个参数是这个类,其他的参数是用来直接传递给 init 方法 3. new 决定是否要使用该 i...
    99+
    2023-01-31
    函数 魔法 Python
  • Python魔法方法如何使用
    这篇“Python魔法方法如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python魔法方法如何使用”文章吧。pyt...
    99+
    2023-07-04
  • PHP5中魔术函数如何使用
    PHP5中魔术函数如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。PHP5魔术函数1,__construct() 当实例化一个对象的时候,这个对象的这个方...
    99+
    2023-06-17
  • python bar函数怎么使用
    在python中使用bar函数绘制一个柱形图,具体方法如下:import matplotlib.pyplot as pltimport numpy as np# 创建一个点数为 8 x 6 的窗口, 并设置分辨率为 80像素/每英寸plt....
    99+
    2024-04-02
  • python偏函数怎么使用
    这篇文章主要介绍python偏函数怎么使用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!说明当函数的参数太多,需要简化时,使用functools.partial可以创建一个新的函数。2、这个新的函数可以固定原始函数的...
    99+
    2023-06-20
  • python super()函数怎么使用
    这篇文章主要介绍“python super()函数怎么使用”,在日常操作中,相信很多人在python super()函数怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python&...
    99+
    2023-06-21
  • python strip函数怎么使用
    strip函数可以用来移除字符串的头尾指定字符,默认移除字符串两端的空格或换行符。基本用法:```pythonstring.stri...
    99+
    2023-09-26
    python
  • python buffer函数怎么使用
    在Python中,buffer()函数用于创建一个缓冲区对象,它可以作为内存对象来处理二进制数据。buffer()函数的语法如下:b...
    99+
    2023-09-23
    python
  • Python split函数怎么使用
    split函数用于将字符串分割成子字符串,并返回一个包含分割后子字符串的列表。split函数的语法是:`str.split(sep=...
    99+
    2023-09-16
    Python
  • Python pow函数怎么使用
    Python中的pow函数用于计算一个数的幂。它的语法如下:pow(x, y, z)其中,x是基数,y是指数,z是可选参数,表示取模...
    99+
    2023-09-22
    Python
  • python timedelta函数怎么使用
    timedelta函数是datetime模块中的一个类,用于表示时间间隔。它可以用于计算日期和时间的差异,以及在日期和时间上进行简单...
    99+
    2023-09-12
    python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作