Python的魔法函数(magic methods)或者特殊方法(Dunder methods)

决定梳理这个内容是因为一个课程,

1. Python语言的魔法函数

1.1 概览

  • 简单来说,在python中,任何以__开头和结尾的函数,都是魔法函数,例如:__init__就是一种魔法函数。
  • 它可以重载默认函数的行为
  • 特殊方法以两个下划线开始,两个下划线结尾。于是乎特殊方法也叫双下方法(dunder method)。dunder,即doubled+underlineunder
    • 命名方式来源参考这里

1.2 介绍

  • 一个可以通过定义具有特殊名称的方法来实现由特殊语法所引发的特定操作 (例如算术运算或下标与切片)。这是 Python 实现 操作符重载 的方式,允许每个类自行定义基于操作符的特定行为
    • 例如,如果一个类定义了名为__getitem__()的方法,并且 x 为该类的一个实例,则x[i] 基本就等同于type(x).__getitem__(x, i)
  • 都是类的方法,所以直接:dir(object)就可以看到支持哪些魔法函数了。
    在这里插入图片描述
  • 如果觉得这个不全面,那么可以去看看dir(dict)等,在这里可以看到一些集合、序列相关的魔法函数。(比如:__iter__
    在这里插入图片描述

参考:Python:实例讲解Python中的魔法函数(高级语法)

下面是抄了一张别人的图,总览一下,然后关于每种魔法函数,了解常见的即可,其余的遇到再说。
在这里插入图片描述

举例说明魔法函数的用处:

魔法函数可以为你写的类增加一些额外功能,方便使用者理解。举个简单的例子,我们定义一个“人”的类People,当中有属性姓名name、年龄age。让你需要利用sorted函数对一个People的数组进行排序,排序规则是按照name和age同时排序,即name不同时比较name,相同时比较age。由于People类本身不具有比较功能,所以需要自定义,你可以这么定义People类:

class People(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        return

    def __str__(self):
        return self.name + ":" + str(self.age)

    def __lt__(self, other):
        return self.name < other.name if self.name != other.name else self.age < other.age


if __name__=="__main__":
    print("\t".join([str(item) for item in sorted([People("abc", 18),
        People("abe", 19), People("abe", 12), People("abc", 17)])]))
    # 补充直观比较
    print(People("abe", 19)<People("abe", 12))

这里有一点需要补充一下,

  • 调用People1<People2的时候,会自动调用魔法函数object.__lt__(self, other)
  • 这里的sorted方法,虽然看不见内部实现,但是大概从函数定义里皆可以知道
@overload
def sorted(__iterable: Iterable[SupportsLessThanT], *, key: None = ..., reverse: bool = ...) -> list[SupportsLessThanT]: ...
@overload
def sorted(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsLessThan], reverse: bool = ...) -> list[_T]: ...
  • 这个函数里肯定用到过小于号或者大于号,参考:python sort函数内部实现原理
  • 可以自己直接比较一下两个People对象,下面这样就比较直观了
    在这里插入图片描述

参考:


2. 其他涉及到python的魔法函数

2.1 IPython的魔法函数

  • 注意,和pyhon的魔法函数进行区分,这里不对IPython的魔法函数多做说明,下面给出的两个参考说的都很详细。

  • 这里就给一个示例,大概知道长什么样就好了

  • 例如:

    %cd
    可以像在命令行一样,切换当前工作目录
    在这里插入图片描述


参考:

2.2 JupyterLab/Jupyter Notebook的魔法函数

在IPython的官网中,有这么一段说明:
在这里插入图片描述
简单翻译一下,就是

广大的Jupyter用户你们好,jupyter中使用魔法命令是由IPython内核提供的。内核上是否支持魔法命令是由内核开发人员决定的(可以配置的)。如果希望可以正常使用魔法命令,则必须使用基础语法中无效的元素。
例如,在IPython内核中使用%语法来使用魔法命令,是因为对于Python来说,%是一个无效的操作符。不过在其他语言中,%可能会具有意义。

由于Jupyter使用的就是IPython内核,所以其中使用的的魔法命令就是IPython的。

3. 其他(minitorch)

minitorch/slides-master/docs/slides+build2/module0.2.html#/22
在这里插入图片描述

魔法函数

  • 任意以__开头或结尾的方法
  • 用于覆盖默认的行为,比如<号原来只可以比较两个数字,重写__lt__方法之后就可以比较任意想要比较的东西
  • 可以用于很多方面,比如操作符重载

猜你喜欢

转载自blog.csdn.net/Castlehe/article/details/121288617