特殊方法的存在是为了Python解释器调用的,你自己并不需要去调用他们,比如说my_object.len()这种写法是没有的,应该使用len(my_object)。在使用len(my_object)的时候,如果my_object是一个自定义类的对象,那么Python会自己去调用其中你实现的len方法。

1.2 如何使用特殊方法

接下来进入1.2节的学习,承接概要我们可以知道自定义类中特殊方法的调用写法,那么如果是Python内置的类型,比如列表(list)、字符串(str)、字节序列(bytearray)等,那么CPython会抄个近路,len实际上会直接返回PyVarObject里的ob_size属性。PyVarObject是表示内存中长度可变的内置对象的语言结构体。直接读取这个值比调用一个方法快很多。

很多时候,特殊方法的调用是隐式的,比如for i in x:这个语句,背后其实用的是iter(x),而这个函数的背后则是x.iter()方法,当然前提是这个方法在x中被实现了。

通常除非有大量元编程存在,否则直接调用特殊方法的频率会远低于去实现他们的次数。唯一的例外可能是init方法,目的是在你自己的字类的init方法中调用超类的构造器。通过内置的函数(例如len、str、iter等等)来使用特殊方法是最好的选择。这些内置函数不仅会调用特殊方法,而且对于内置类来说,他们速度更快。

1.2.1 模拟数值类型

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

我们首先实现一个二维向量(vector)类

示例 1-2 一个简单的二维向量类1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23from math import hypot

class Vector:

def __init__(self, x=0, y=0):

self.x = x

self.y = y

def __repr__(self):

return 'Vector(%r, %r)' % (self.x, self.y)

def __abs__(self):

return hypot(self.x,self.y)

def __bool__(self):

return bool(abs(self))

def __add__(self, other):

x = self.x + other.x

y = self.y + other.y

return Vector(x,y)

def __mul__(self, scalar):

return Vector(self.x * scalar, self.y * scalar)

接下来对类里面的特殊方法进行操作

1

2

3

4

5

6

7

8

9

10

11

12

13v = Vector(3,4)

v1 = Vector(2,4)

v2 = Vector(2,1)

print(abs(v))

print(v1+v2)

print(v*3)

print(abs(v*3))

Output:

5.0

Vector(4, 5)

Vector(9, 12)

15.0

这里使用+运算符得到的结果也是一个向量,abs函数是一个内置函数,如果输入的是整数或者浮点数,他返回的是输入值的绝对值,如果输入的是复数,那么返回这个复数的模。为了保持一致性,我们的API在碰到abs函数的时候,也应该返回该向量的模。

使用*运算符来实现向量的标量乘法(即向量与数的乘法,得到的结果向量的方向与原向量一致,模变大),接下来看看每个特殊方法的实现。

1.2.2 字符串表示形式

Python有一个内置的函数叫repr,它能把一个对象用字符串的形式表达出来以便辩认,这就是“字符串表示形式”。repr就是用过repr这个特殊方法来得到一个对象的字符串形式的。如果没有实现repr,当我们在控制台打印一个向量的实例时,得到的字符串可能会是。repr

交互式控制台和调试程序(debugger)用repr函数来获取字符串表示形式;在老的使用%符号的字符串格式中,这个函数返回的结果用来代替%r所代表的对象;同样str.format函数所使用的新式字符串格式化语法也是利用了repr,才!r字段变成字符串

在repr的实现中,我们用到了%r来获取对象各个属性的标准字符串表示形式,它暗示了一个关键:Vector(1,2)和Vector(‘1’,’2’)是不一样的,后者在我们的定义中会报错,因为向量对象的构造函数只接受数值,不接受字符串。

repr和str的区别在于,后者是在str()函数被使用,或是在用print函数打印一个对象的时候才被调用的,并且它返回的字符串对终端用户更友好。(%s对应于str()处理后的对象,%r对应于repr()处理后的对象)

1.2.3 算术运算符

通过add和mul,示例1-2为向量类带来了+和*这两个算术运算符,这两个方法中的返回值都是新创建的向量对象,被操作的两个向量(self或other)还是原封不动,代码里只是读取了它们的值。中缀运算符的基本原则就是不改变操作对象,而是产出一个新的值。

1.2.4 自定义的布尔值

为了判定一个值x为真还是为假,Python会调用bool(x),这个函数只能返回True或者False。

默认情况下,我们自己定义的类的实例总被认为是真的,除非这个类对bool或者len函数有自己的实现。bool(x)的背后是调用bool()的结果,如果不存在bool方法,那么bool(x)会尝试调用x.len()。若返回0,则bool会返回False,否则返回True。

我们自己定义的类中,bool方法的实现比较简单,如果向量的模是0,那么返回False,其他情况返回True。

如果想让Vector.bool更高效,可以采用这种实现:1

2def __bool__(self):

return bool(self.x or self.y)

因为只有横坐标和纵坐标同时为0时该向量模为0,所以只要取两坐标的“或”值,同时为0时才返回0 来代替abs到abs到平方再到平方根这些中间步骤。

python读书笔记2000_流畅的Python读书笔记相关推荐

  1. 读书笔记:《流畅的Python》第五章 一等函数

    # 一等对象/一等函数 ''' 1.在运行时创建 2.能赋值给变量或数据结构中的元素 3.能作为函数的参数传给函数 4.能作为函数的返回值返回结果 '''# 函数对象本身时function对象的实例d ...

  2. 还没学python_2个月过去了!还没学会python?用《流畅的python》15天带你学会

    学了很久python,还是完全没有思路 自己学了很久的python,还是感觉没学到什么,出现这样的情况的python学习者有很多,只是大多都是放弃了! 出现这样的原因主要有以下三点: 1.没有人带领, ...

  3. 读书笔记:《流畅的Python》第19章 动态属性和特性

    # 第19章 动态属性和特性""" 属性(attribute):数据的属性和处理数据的方法统称属性,方法只是可调用的属性. 特性(property)除此之外,我们海可以创 ...

  4. 读书笔记:《流畅的Python》第21章 类元编程

    # 第21章 类元编程""" 类元编程指的是运行时创建或定制类的技艺1.类是一等对象,任何时候都可以使用函数新建类,而无需使用class关键字2.类装饰器也是函数,不过能 ...

  5. 51假期读书笔记(下)——流畅的python

    5.45.45.4 可调用对象 除了用户定义的函数,调用运算符(即())还可以应用到其他对象上.如果想判断对象能否调用,可以使用内置的callable()函数.Python的数据模型文档列出了以下7种 ...

  6. 51假期读书笔记(上)——流畅的python

    今天是51假期,我开启了新的一章,✌️! 第五章 一等函数 编程语言理论家将"一等对象"定义为满足下述条件的程序实体: 在运行时创建 能赋值给变量或者数据结构中的元素 能作为参数传 ...

  7. 读书笔记:《流畅的Python》第17章 使用future处理并发

    # 第17章 使用future处理并发""" 内容提要:concurrent.futures模块future的概念:是一种对象,表示异步执行的操作是concurrent. ...

  8. 读书笔记:《流畅的Python》第4章 文本和字节序列

    # 第四章 文本和字节序列"""内容提要:1.Unicode字符串2.二进制序列3.在二者之间转换使用的编码4.字符/码位/字节表述5.bytes/bytearray/m ...

  9. 读书笔记:《流畅的Python》第15章 上下文管理器和else块

    # 第15章 上下文管理器和else块""" 本章内容提要:with语句和上下文管理器for while try语句的else子句 """# ...

最新文章

  1. 荣耀有可能搭载鸿蒙系统吗,如果荣耀Magic3搭载了屏下镜头和鸿蒙系统,你会做第一批吗?...
  2. c语言经典算法——查找一个整数数组中第二大数
  3. windows7安装openssh
  4. 情人节程序员用HTML网页表白【时光不老,我们不散love520】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
  5. 网卡5790c linux驱动,(支持所有硬件、无需连接宽带)e驱动 v5.21 WIN7 32bit专版驱动包...
  6. 用original绘制重叠柱状图
  7. 我的知识星球 -【达叔与他的朋友们】程序员
  8. Python:正则表达式re.compile()
  9. [论文笔记]Feature-constrained Active Visual SLAM for Mobile Robot Navigation
  10. 宝塔Linux面板 软件商店中安装不了任何php版本的解决方法
  11. sqlite编辑器 linux,SQLite编辑器
  12. 深度学习中number of training epochs中的,epoc h到底指什么?
  13. JSD-2204-连接查询-JDBC-Day10
  14. 企业文化如何推动绩效?
  15. Kronecker积
  16. word字体设置:如何为常用字体设置快捷键
  17. C++ Qt获取windows任务栏的位置及高度
  18. VSC/SMC(十四)——全局快速Terminal滑模控制(含程序模型)
  19. JavaBean对象与jfinal的Record对象互转
  20. 物联网毕设 单片机 嵌入式 题目选题推荐

热门文章

  1. Heroku和Java –从新手到初学者,第1部分
  2. 您的日志就是您的数据:logstash + elasticsearch
  3. IBM AIX:Java进程大小监视
  4. python编码程序_python 编码
  5. c++ vs 输出log到窗口_欧冠豪门碰撞,尤文vs巴萨,曼联vs红牛
  6. Linux 的权限表达式
  7. 反码、原码、补码的观点阐述
  8. 树莓派python交互界面实例_玩转树莓派-RaspBerry,使用Python开发定制界面
  9. hibernate框架 最新_java框架,使用最频繁的9个程序!
  10. oracle数据库集群日志,Oracle集群数据库中恢复归档日志