对象
按某份类的描述造出来的具体个体,带着自己的数据,并能响应该类提供的方法。
它是什么
对象 是程序运行时实际存在的一个东西:它属于某个 类,带着自己的属性,能响应该类提供的方法。3 是整数对象,"观测" 是字符串对象,按图纸构造的 Point(3, 4) 也是对象。说「一切都是对象」,意思是值可以被传递、拥有 类型、往往还带有方法,而不是说必须把每一行都写成 class。
p = Point(3, 4)
p.move(1, 0)这里 p 指向一个具体的点。另一个 q = Point(0, 0) 是另一个对象,移动 p 不会带动 q。身份、类型、值是理解对象常用的三个角度:它是哪一个、它属于哪一类、它当前表示什么。
名字从哪来
object 在日常英语里就是「物体」。面向对象(object-oriented)这个说法在 1960–70 年代由艾伦·凯(Alan Kay)等人推广:程序不再只是一串过程,而是一群互相发消息的个体。Python 选择让数字、函数、模块 也都以对象的形式出现,风格统一。
对象只能表示看得见的实物——这是对这个词的误读。一次方程的解、一次文件读取的结果、一个错误,都可以是对象。见 异常。
它怎么工作
构造对象时,类的 __init__ 先跑一遍,把初始数据挂到这个个体上。之后,方法通过 self 找到这些数据。赋值 b = a 若 a 是对象,通常让两个名字指向同一个个体。改 a 能看见的可变部分,b 也会看见。这和「复制一份全新的对象」不是一回事。
对象用完以后,如果没有任何名字再指向它,解释器可以回收这块内存。两个对象打印出来长得一样,不必是同一个:== 比的往往是值;is 比的是是不是同一个个体。把值相等和身份相同混为一谈,会在别名与拷贝之间迷路。
生活里在哪里
同一张图纸建出的两栋房子:格局相同,家具不同。两名学生都是「学生」这一类,学号不同。两只海龟画笔都可以前进转弯,但位置各自独立,见 海龟画图。生活里很少需要把「类别」和「这个人」说成同一个词;程序里同样如此。能给对象加属性,不等于这一类事物在模型里就该有这些属性。
和相近概念的差别
类描述可能性,对象是其中一次实现。变量 是指向对象的名字,不是对象本身。名字可以改去指向别人;对象在没人指向之前一直在。数字、字符串等内置对象每天都在用,即使还没有写出 class 这个词。
元组、列表、字典都是对象。选用哪一种,取决于问题要问顺序、键还是唯一性,而不是「只要是对象就够了」。抽象关心的是接口;对象是接口所作用的那个具体承载者。
常见误会
误会 1:两个对象打印出来长得一样,就是同一个。
值相等和身份相同不是一回事。== 与 is 问的是不同的问题。
误会 2:把对象当字典用,随便加一堆互不相关的属性。
能加不等于应该加。类的意义就是约束「这一类该有什么」。
误会 3:对象只能表示看得见的实物。
解、错误、一次读取的结果,都可以是对象。模型里的东西不必能被拍照。
想知道更多
- 书:布鲁克希尔《计算机科学概论》
- 书:艾伦·唐尼《像计算机科学家一样思考Python(第2版)》
- 书:埃里克·马瑟斯《Python编程:从入门到实践(第3版)》
未登录时不会保存学习进度