Python编程:从入门到实践
章节

第 9 章 类

当程序需要描述对象、状态和行为时,类就登场了

这一章把面向对象的最小框架交给读者:类、实例、属性、方法、继承和组合。

章节主张

类的核心不是高级语法感,而是它让复杂程序能围绕对象组织状态与行为。

中文释读

很多人一听类就紧张,其实这章讲的是很朴素的事:如果你反复在处理同一种对象,那么就让对象自己带着属性和动作。Dog、Car、ElectricCar、Battery 这些例子都在不断降低抽象门槛。真正需要抓住的是:类让数据和操作重新靠近,也让大型程序的结构开始稳定下来。

本章知识路线

  1. 类是在把世界切成可协作的对象
  2. 继承是复用,组合是控复杂,两者要会取舍

关键论点

  • 类适合描述拥有共同属性和行为的一类对象。
  • 继承和组合是组织复杂对象结构的两种主要方式。
  • 把类拆分成协同小类能降低复杂度。

行动清单

  • 用类之前先判断对象是否真的稳定重复出现。
  • 分清类属性、实例属性与方法职责。
  • 遇到类变胖时考虑组合而不是盲目继续加方法。

源章节深读

第 9 章 类 ⾯向对象编程( object-oriented programming , OOP )是最有效的软件编 写⽅法之⼀。在⾯向对象编程中,你编写表⽰现实世界中的事物和情 景的类( class ),并基于这些类来创建对象( object )。在编写类时, 你要定义⼀批对象都具备的通⽤⾏为。在基于类创建对象时,每个对 象都⾃动具备这种通⽤⾏为。然后,你可根据需要赋予每个对象独特 的个性。使⽤⾯向对象编程可模拟现实情景,逼真程度到达了令⼈惊 讶的地步。 根据类来创建对象称为实例化,这让你能够使⽤类的实例( instance )。在 本章中,你将编写⼀些类并创建其实例。你将指定可在实例中存储什么信 息,定义可对这些实例执⾏哪些操作。你还将编写⼀些类来扩展既有类的 功能,让相似的类能够共享功能,从⽽使⽤更少的代码做更多的事情。你 将把⾃⼰编写的类存储在模块中,并在⾃⼰的程序⽂件中导⼊其他程序员 编写的类。 学习⾯向对象编程有助于你像程序员那样看世界,并且真正明⽩⾃⼰编写 的代码:不仅是各⾏代码的作⽤,还有代码背后更宏⼤的概念。了解类背 后的概念可培养逻辑思维能⼒,让你能够通过编写程序来解决遇到的⼏乎 任何问题。

9.1 创建和使用类

9.1 创建和使⽤类 使⽤类⼏乎可以模拟任何东⻄。下⾯来编写⼀个表⽰⼩狗的简单类 Dog —— 它表⽰的不是特定的⼩狗,⽽是任何⼩狗。对于⼤多数宠物狗,我们 都知道些什么呢?它们都有名字和年龄。我们还知道,⼤多数⼩狗还会坐 下和打滚。由于⼤多数⼩狗具备上述两项信息(名字和年龄)和两种⾏为 (坐下和打滚),我们的 Dog 类将包含它们。这个类让 Python 知道如何创 建表⽰⼩狗的对象。编写这个类后,我们将使⽤它来创建表⽰特定⼩狗的 实例。

这节解决什么:这一节主要解决《第 9 章 类》里一个更具体的子问题:9.1 创建和使用类 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

9.2 使用类和实例

9.2 使⽤类和实例 可以使⽤类来模拟现实世界中的很多情景。类编写好后,你的⼤部分时间 将花在使⽤根据类创建的实例上。你需要完成的⾸要任务之⼀是,修改实 例的属性。既可以直接修改实例的属性,也可以编写⽅法以特定的⽅式进 ⾏修改。

这节解决什么:这一节主要解决《第 9 章 类》里一个更具体的子问题:9.2 使用类和实例 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

9.3 继承

9.3 继承 在编写类时,并⾮总是要从头开始。如果要编写的类是⼀个既有的类的特 殊版本,可使⽤继承( inheritance )。当⼀个类继承另⼀个类时,将⾃动获 得后者的所有属性和⽅法。原有的类称为⽗类( parent class ),⽽新类称为 ⼦类( child class )。⼦类不仅继承了⽗类的所有属性和⽅法,还可定义⾃ ⼰的属性和⽅法。 9.3.1 ⼦类的 __init__() ⽅法 在既有的类的基础上编写新类,通常要调⽤⽗类的 __init__() ⽅法。

这节解决什么:这一节主要解决《第 9 章 类》里一个更具体的子问题:9.3 继承 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

9.4 导入类

9.4 导⼊类 随着不断地给类添加功能,⽂件可能变得很⻓,即便妥善地使⽤了继承和 组合亦如此。遵循 Python 的整体理念,应该让⽂件尽量整洁。 Python 在这 ⽅⾯提供了帮助,允许你将类存储在模块中,然后在主程序中导⼊所需的 模块。 9.4.1 导⼊单个类 下⾯创建⼀个只包含 Car 类的模块。有⼀个微妙的命名问题:在本章中, 已经有⼀个名为 car.py 的⽂件,但这个模块也应命名为 car.py ,因为它包含 表⽰汽⻋的代码。

这节解决什么:这一节主要解决《第 9 章 类》里一个更具体的子问题:9.4 导入类 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

9.5 Python 标准库

9.5 Python 标准库 Python 标准库是⼀组模块,在安装 Python 时已经包含在内。你现在已经对 函数和类的⼯作原理有了⼤致的了解,可以开始使⽤其他程序员编写好的 模块了。你可以使⽤标准库中的任何函数和类,只需在程序开头添加⼀条 简单的 import 语句即可。下⾯来看看模块 random,它在你模拟很多现 实情况时很有⽤。 在这个模块中,⼀个有趣的函数是 randint()。它将两个整数作为参数, 并随机返回⼀个位于这两个整数之间(含)的整数。

这节解决什么:这一节主要解决《第 9 章 类》里一个更具体的子问题:9.5 Python 标准库 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

9.6 类的编程风格

9.6 类的编程⻛格 你必须熟悉有些与类相关的编程⻛格问题,在编写的程序较复杂时尤其如 此。 类名应采⽤驼峰命名法,即将类名中的每个单词的⾸字⺟都⼤写,并且不 使⽤下划线。实例名和模块名都采⽤全⼩写格式,并在单词之间加上下划 线。 对于每个类,都应在类定义后⾯紧跟⼀个⽂档字符串。这种⽂档字符串简 要地描述类的功能,你应该遵循编写函数的⽂档字符串时采⽤的格式约 定。每个模块也都应包含⼀个⽂档字符串,对其中的类可⽤来做什么进⾏ 描述。 可以使⽤空⾏来组织代码,但不宜过多。

这节解决什么:这一节主要解决《第 9 章 类》里一个更具体的子问题:9.6 类的编程风格 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

9.7 小结

9.7 ⼩结 在本章中,你⾸先学习了如何编写类,如何使⽤属性在类中存储信息,以 及如何编写⽅法让类具备所需的⾏为。然后学习了如何编写 __init__() ⽅法,以便根据类创建包含所需属性的实例。你了解了如何修改实例的属 性,包括直接修改以及通过⽅法修改。你还了解到,使⽤继承可简化相关 类的创建⼯作,将⼀个类的实例⽤作另⼀个类的属性能让类更简洁。 接着,你明⽩了,通过将类存储在模块中,并在需要使⽤这些类的⽂件中 导⼊它们,可让项⽬变得整洁。

这节解决什么:这一节主要解决《第 9 章 类》里一个更具体的子问题:9.7 小结 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

辨析题

为什么作者在讲类时反复用现实对象举例?

本章图版学习路径

类是在把世界切成可协作的对象

继承是复用,组合是控复杂,两者要会取舍