流畅的Python:第一章 特殊方法

Python解释器

Python 解释器碰到特殊的句法时,会使⽤用特殊⽅方法去激活⼀些基本的对象操作,这些特殊方法的名字以两个下划线开头,以两个下划线结尾(例如__getitem__) 。

显式还是隐式

迭代通常是隐式的,譬如说一个集合类型没有实现 __contains__方法,那么 in 运算符就会按顺序做一次迭代搜索。

如何使用特殊方法

调用方式

特殊方法的存在是为了被Python 解释器调用的,你自己并不需要调用它们。

关于内置类型

然而如果是 Python 内置的类型,比如列表(list) 、字符串(str) 、字节序列(bytearray)等,那么
CPython 会抄个近路,__len__实际上会直接返回 PyVarObject里的 ob_size 属性。

模拟数值类型

利用特殊方法,可以让自定义对象通过加号“+” (或是别的运算符)进行运算。

字符串表示形式

Python 有一个内置的函数叫repr,它能把一个对象用字符串的形式表达出来以便辨认,这就是“字符串表示形式” 。

  1. repr 就是通过__repr__这个特殊方法来得到一个对象的字符串表示形式的。
  2. __repr__的实现中,我们用到了 %r 来获取对象各个属性的标准字符串表示形式。
  3. __repr__所返回的字符串应该准确、无歧义,并且尽可能表达出如何用代码创建出这个被打印的对象。
  4. __repr____str__的区别在于,后者是在 str() 函数被使用,或是在用 print 函数打印一个对象的时候才被调用的,并且它返回的字符串对终端用户更友好。

算术运算符

加法与乘法的特殊方法是:__add____mul__,乘法交换律的特殊方法是:__rmul__

自定义的布尔值

  1. 任何对象都可以用于需要布尔值的上下文中(比如if 或 while 语句,或者 and、or 和 not 运算符)
  2. 默认情况下,我们自己定义的类的实例总被认为是真的,除非这个类对 __bool__ 或者__ len__函数有自己的实现。
  3. bool(x) 的背后是调用 x.__bool__() 的结果;如果不存在__ bool__方法,那么 bool(x) 会尝试调用 x.__len__()

特殊方法一览

在这里插入图片描述
在这里插入图片描述

为什么 len 不是普通方法

  1. 是为了让 Python 自带的数据结构可以走后门,如果 x 是一个内置类型的实例,那么 len(x) 的速度会非常快。背后的原因是 CPython 会直接从一个 C 结构体里读取对象的长度,完全不会调用任何方法。
  2. 可以把 len 用于自定义数据类型
  3. 这种处理方式在保持内置类型的效率和保证语言的一致性之间找到了一个平衡点

本章小结

  1. __repr____str__,Python 对象的一个基本要求就是它得有合理的字符串表示形式,前者方便我们调试和记录日志,后者则是给终端用户看的。
  2. 对序列数据类型的模拟是特殊方法用得最多的地方。
  3. Python 通过运算符重载这一模式提供了丰富的数值类型,除了内置的那些之外,还有decimal.Decimalfractions.Fraction。这些数据类型都支持中缀算术运算符。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值