• 漫谈Python魔术方法,见过的没见过的都在这里了


    漫谈Python魔术方法,见过的没见过的都在这里了

    就说一下,不深入

    假的一览

    数据模型

    https://docs.python.org/zh-cn/3.9/reference/datamodel.html#special-method-names

    以3.9为例

    • 最全的还是在官方(但仍然会有漏网之鱼)
    • 我稍作整理,仅供参考

    1. ★基本定制

    方法 说明
    __init__(self[, ...]) 所谓的初始化,在实例 (通过__new__) 被创建之后,返回调用者之前调用
    __new__(cls[, ...]) 调用以创建一个 cls 类的新实例
    __del__(self) 在实例将被销毁时调用。 这还被称为终结器或析构器(不适当)
    __repr__(self) 由 repr() 内置函数调用以输出一个对象的“官方”字符串表示
    __str__(self) 通过 str(object) 以及内置函数 format() 和 print() 调用以生成一个对象的“非正式”或格式良好的字符串表示
    __bytes__(self) 通过 bytes 调用以生成一个对象的字节串表示
    __format__(self,format_spec) 通过 format() 内置函数、扩展、格式化字符串字面值 的求值以及 str.format() 方法调用以生成一个对象的“格式化”字符串表示
    __hash__(self) 通过内置函数 hash() 调用以对哈希集的成员进行操作,属于哈希集的类型包括 set、frozenset 以及 dict。__hash__() 应该返回一个整数
    __bool__(self) 调用此方法以实现真值检测以及内置的 bool() 操作;应该返回 FalseTrue

    2. 富比较方法

    方法 说明
    __lt__(self, other) 小于
    __le__(self, other) 小于等于
    __eq__(self, other) 等于
    __ne__(self, other) 不等于
    __gt__(self, other) 大于
    __ge__(self, other) 大于等于

    3. ★自定义属性访问

    方法 说明
    __getattr__(self, name) 当默认属性访问因引发 AttributeError 而失败时被调用
    __getattribute__(self, name) 此方法会无条件地被调用以实现对类实例属性的访问
    __setattr__(self, name, value) 此方法在一个属性被尝试赋值时被调用
    __delattr__(self, name) 类似于 __setattr__() 但其作用为删除而非赋值
    __dir__(self) 此方法会在对相应对象调用 dir() 时被调用

    4. ★实现描述器

    方法 说明
    __get__(self, instance, owner=None) 调用此方法以获取所有者类的属性(类属性访问)或该类的实例的属性(实例属性访问)
    __set__(self, instance, value) 用此方法以设置 instance 指定的所有者类的实例的属性为新值 value
    __delete__(self, instance) 调用此方法以删除 instance 指定的所有者类的实例的属性。
    __set_name__(self, owner, name) 在所有者类 owner 创建时被调用。描述器会被赋值给 name

    5. 自定义类创建

    方法 说明
    __init_subclass__(cls) 当所在类派生子类时此方法就会被调用

    6. 自定义实例及子类检查

    方法 说明
    __instancecheck__(self, instance) 如果 instance 应被视为 class 的一个(直接或间接)实例则返回真值
    __subclasscheck__(self, subclass) 如果 subclass 应被视为 class 的一个(直接或间接)子类则返回真值

    7. 模拟泛型类型

    方法 说明
    __class_getitem__(cls, key) 按照 key 参数指定的类型返回一个表示泛型类的专门化对象。
    • 当在类上定义时,__class_getitem__() 会自动成为类方法。 因此,当它被定义时没有必要使用 @classmethod 来装饰。

    8. ★模拟可调用对象

    方法 说明
    __call__(self[, args...]) 此方法会在实例作为一个函数被“调用”时被调用

    9. ★模拟容器类型

    方法 说明
    __len__(self) 调用此方法以实现内置函数 len()。应该返回对象的长度
    __length_hint__(self) 调用此方法以实现 operator.length_hint()。 应该返回对象长度的估计值(可能大于或小于实际长度)
    __getitem__(self, key) 调用此方法以实现 self[key] 的取值(注:官文是未付,英文是evaluation)
    __setitem__(self, key, value) 调用此方法以实现向 self[key] 赋值
    __delitem__(self, key) 调用此方法以实现 self[key] 的删除
    __missing__(self, key) 此方法由 dict.__getitem__() 在找不到字典中的键时调用以实现 dict 子类的 self[key]
    __iter__(self) 此方法在需要为容器创建迭代器时被调用
    __reversed__(self) 此方法(如果存在)会被 reversed() 内置函数调用以实现逆向迭代
    __contains__(self, item) 调用此方法以实现成员检测运算符in

    10. ★模拟数字类型

    方法 说明
    __add__(self, other) +
    __sub__(self, other) -
    __mul__(self, other) *
    __matmul__(self, other) @这个你可能没听过
    __truediv__(self, other) 除法 /
    __floordiv__(self, other) 地板除 //
    __mod__(self, other) 取余 %
    __pow__(self, other[,modulo]) 幂运算 **
    __lshift__(self, other) 左移 <<
    __rshift__(self, other) 右移 >>
    __and__(self, other) & 与
    __xor__(self, other) ^ 异或
    __or__(self, other) | 或
    • 上面的方法再加个r又是另外一大类
    方法 说明
    __radd__(self, other) +
    __rsub__(self, other) -
    __rmul__(self, other) *
    __rmatmul__(self, other) @
    `rtruediv(self, other) /
    __rfloordiv__(self, other) //
    __rmod__(self, other) 取余 %
    __rpow__(self, other[,modulo]) 幂运算 **
    __rlshift__(self, other) 左移 <<
    __rrshift__(self, other) 右移 >>
    __rand__(self, other) &
    __rxor__(self, other) ^
    __ror__(self, other) |
    • 调用这些方法来实现具有反射(交换)操作数的二进制算术运算 (+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |)。这些成员函数仅会在左操作数不支持相应运算 3 且两个操作数类型不同时被调用。4 例如,求表达式 x - y 的值,其中 y 是具有 __rsub__() 方法的类的一个实例,则当 x.__sub__(y) 返回 NotImplemented 时会调用 y.__rsub__(x)

      请注意三元版的 pow() 并不会尝试调用 __rpow__() (因为强制转换规则会太过复杂)


    • 加个i又是另外一套
    方法 说明
    __iadd__(self, other) +=
    __isub__(self, other) -=
    __imul__(self, other) *=
    __imatmul__(self, other) @=
    __itruediv__(self, other) /=
    __ifloordiv__(self, other) //=
    __imod__(self, other) %=
    __ipow__(self, other[,modulo]) **=
    __ilshift__(self, other) <<=
    __irshift__(self, other) >>=
    __iand__(self, other) &=
    __ixor__(self, other) ^=
    __ior__(self, other) |=
    • 调用上面这些方法来实现扩展算术赋值

    • 数字是最多的
    • 不光上面的,还要一些
    方法 说明
    __neg__(self) 一元运算符 -
    __pos__(self) 一元运算符 +
    __abs__(self) abs()
    __invert__(self) 一元运算符 ~
    __complex__(self) 实现内置函数complex()
    __int__(self) 实现内置函数int()
    __float__(self) 实现内置函数float()
    __index__(self) 调用此方法以实现 operator.index()
    __round__(self[,ndigits]) 实现内置函数round()
    __trunc__(self) 实现内置函数trunc()
    __floor__(self) 实现内置函数floor()
    __ceil__(self) 实现内置函数ceil()

    11. 上下文管理器

    方法 说明
    __enter__(self) 进入与此对象相关的运行时上下文
    __exit__(self, exc_type, exc_value, traceback) 退出关联到此对象的运行时上下文

    12. 协程相关

    可等待对象

    方法 说明
    __await__(self) awaitable 对象主要实现了该方法,它必须返回一个 iterator

    异步迭代器

    方法 说明
    __aiter__(self) 必须返回一个 异步迭代器 对象
    __anext__(self) 必须返回一个 可迭代对象 输出迭代器的下一结果值

    异步上下文管理器

    方法 说明
    __aenter__(self) 在语义上类似于 __enter__(),仅有的区别是它必须返回一个 可等待对象
    __aexit__(self) 在语义上类似于 __exit__(),仅有的区别是它必须返回一个 可等待对象

    00. 漏网之鱼

    方法 说明
    __objclass__ 会被 inspect 模块解读为指定此对象定义所在的类
    __slots__ 允许我们显式地声明数据成员(如特征属性)并禁止创建 dictweakref
    __mro_entries__
    __prepare__
    __class__
    __classcell__

    说在最后

    • 码农高天出了一个系列讲解魔术方法,推荐观看https://www.bilibili.com/video/BV1b84y1e7hG

    • 流畅的python对魔术方法的讲解比较深入,贯穿全文,有一定难度,基础薄弱的谨慎

    • 前面在哪里说过很多内置函数、操作、运算符的背后多数都是这些魔术方法的实现。

      • with上下文管理器的背后是__enter__(self)__exit__(self, exc_type, exc_value, traceback)
      • 多数的运算符背后都是的10. 模式数字类型
      • 内置函数如len的背后是__len__
  • 相关阅读:
    C++:mismatch容器比较函数(获取首个不符合条件的元素)
    nRF52832 之ADC的使用
    电脑重装系统后usbcleaner怎么格式化u盘
    【Java】复制数组的四种方式
    复习Day03:数组part03:76 . 最小覆盖子串、438. 找到z字符串z中所有字母异位词
    5G NR学习入门
    Winform +OpenCvSharp更换证件照底色
    PyTorch的自动求导
    String转JsonObject 再转list<Map<String,Object>>
    若依前端vue设置子路径
  • 原文地址:https://www.cnblogs.com/wuxianfeng023/p/17198774.html