Python 魔术方法 - zhongjiajie/zhongjiajie.github.com GitHub Wiki

Python-魔术方法

首先明确一点,特殊方法的存在是为了被 Python 解释器调用的,你自己并不需要调用它们。也就是说没有 my_object.__len__()这种写法,而应该使用len(my_object)在执行len(my_object)的时 候,如果 my_object 是一个自定义类的对象,那么 Python 会自己去调用其中由你实现的 __len__ 方法。

通过内置的函数(例如 leniterstr,等等)来使用特殊方法是最好的选择。这些内置函数不仅会调用特殊方法,通常还提供额外的好处,而且对于内置的类来说,它们的速度更快

假设定义了一个类Magic,那么定义了魔术方法后会有如下的效果

魔术方法在data model中有较为详细和完整的介绍

跟运算符无关的特殊方法

字符串 字节序列

  • __repr__: 定义返回对象的格式,调用这个对象时返回的格式(一般面向的时程序员),在REPL中输入这个对象时输出属于__repr__,被repr或者print函数调用
  • __str__: 定时输出的格式,类似print(object)的输出格式(一般面向的时用户),如果__str__没有定义但是__repr__有定义时print会输出__repr__的值,被str函数调用
    • __repr____str__的区别Difference between str and repr
    • __repr__注重准确性
    • __str__注重可读性
    • 容器的__str__包括了__repr__
      • 如果__repr__定义了但是__str__没有定义,就会__str__=__repr__
  • __format__:
  • __bytes__:

数值转换

  • __abs__: 获取对象的绝对值,通过abs函数调用
  • __bool__: 返回对象的bool类型,通过bool函数调用,可以用于if while and or not的组合运算.默认情况下,我们自己定义的类的实例总被认为是真的(如果__bool____len__没有定义),如果只定义了__bool__没有定义__len__则调用bool(obj)的时候会调用__len__,为0则返回False,反之返回True
  • __complex__:
  • __int__:
  • __float__:
  • __hash__:
  • __index__:

集合模拟

  • __len__: 获取序列的长度,被len函数调用.如果对象是一个内置类型,len()方法会非常快,背后的原因是 CPython 会直接从一个 C 结构体里读取对象的长度,完全不会调用任何方法.len不是一个普通方法,len 之所以不是一个普通方法,是为了让 Python 自带的数据结构可以走后门
  • __getitem__: 使序列的[]方法生效,可以对其进行索引,切片,变成可迭代对象用for进行迭代,用in方法判断元素是否在序列中(__contains__方法应该更好些)
  • __setitem__:
  • __delitem__:
  • __contains__:

迭代枚举

  • __iter__:
  • __reversed__:
  • __next__:

可调用模拟

  • __call__:

上下文管理

  • __enter__:
  • __exit__:

实例创建和销毁

  • __new__:
  • __init__:
  • __del__:

属性管理

  • __getattr__:
  • __getattribute__:
  • __setattr__:
  • __delattr__:
  • __dir__:

属性描述符

  • __get__:
  • __set__:
  • __delete__:

类相关的服务

跟运算符相关的特殊方法

一元运算符

  • __neg__: -
  • __pos__: +
  • __abs__: abs()

算术运算符

  • __add__: + 通过+中缀运算符调用,返回新对象,原对象不变,add
  • __sub__: - subtract
  • __mul__: * 通过*中缀运算符调用,返回新对象,原对象不变,multiply
  • __div__: / divide, 现在一般用 __truediv__代表
  • __truediv__: / divide
  • __floordiv__: //
  • __mod__: % 取余数
  • __divmod__: divmod()
  • __pow__: **pow()
  • __round__: round()
  • __iadd__: 自增的加,+=,对于可变对象相当于在可变对象调用append或者extend,这个时候的对象是原来的对象, id(Object)的值是不变的如果没有实现这个功能,则会调用__add__,但是此时的对象id已经变成了别的id了,不可变对象一般不会实现这个功能,不可变对象使用+=的时候会调用__add__功能,生成一个新对象
  • __imul__: 与__iadd__类似

比较运算符

  • __lt__: <
  • __le__: <=
  • __eq__: ==
  • __ne__: !=
  • __gt__: >
  • __ge__: >=

⚠️ **GitHub.com Fallback** ⚠️