自学Python

Chapter 4

第4章Python面向对象编程

章节主张

第4章Python面向对象编程这一章真正要建立的,不是孤立知识点,而是围绕“面向对象是把数据和行为捆在一起管理、环境与工具链先于语法细节”形成一套能反复练习、能迁移到真实任务里的 Python 学习路径。

中文释读

读 第4章Python面向对象编程 时,不要只把它当作语法或模块说明书。更有价值的读法,是问自己:这一章解决了我在编程、科学计算或数据分析流程中的哪个瓶颈?

这本书的强项在于把工具、基础语法、科学计算库和案例工作流连成一条线。章节页因此会把原书内容翻译成“知识点 -> 操作动作 -> 易错边界 -> 迁移练习”的学习结构。

本章知识路线

关键论据

  • 对象一般是指一个类的实例,具有相关的成员变量和成员函数,在Python中成员变量叫作属性,成员函数叫作方法。
  • 类 (Class)通常是具有一类共同特征的事物的抽象。
  • 它的一个实例叫作 对象 (Object)。
  • 1.什么是对象 Python中几乎所有的事物都是对象。
  • 基本类型是对象,如整数: 其类型为: 查看它的属性: 调用它的方法: 容器类型是对象,如列表: 函数是对象: 对象在内存中有一个地址与之对应,这个地址可以用id()函数查看: 同一个对象的内存地址一致: id()函数本身也是对象,对应一块内存地址: 在Python中,只有一些保留的关键字和符号不是对象: 2.对象的特性 对象的两个重要特性是属性和方法。

行动清单

  • 先用最小代码样例跑通本章核心知识点。
  • 把本章知识点接到一个真实小任务上,而不只停留在示例。
  • 记录本章最容易报错的边界条件和调试方式。
  • 复盘:这一章内容如何进入自己的长期 Python 学习系统。

本章图版学习路径

图版按知识点分组,适合拿来做复现、迁移和复盘练习,不只是“看一眼效果”。

源章节深读

4.1 面向对象简介

这节解决什么问题:这节要解决的不是背下“4.1 面向对象简介”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“4.1 面向对象简介”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 4.1 面向对象简介 背后的对象模型、输入输出和适用边界。

对象一般是指一个类的实例,具有相关的成员变量和成员函数,在Python中成员变量叫作属性,成员函数叫作方法。 类 (Class)通常是具有一类共同特征的事物的抽象。它的一个实例叫作 对象 (Object)。 1.什么是对象 Python中几乎所有的事物都是对象。基本类型是对象,如整数: 其类型为: 查看它的属性: 调用它的方法: 容器类型是对象,如列表: 函数是对象: 对象在内存中有一个地址与之对应,这个地址可以用id()函数查看: 同一个对象的内存地址一致: id()函数本身也是对象,对应一块内存地址: 在Python中,只有一些保留的关键字和符号不是对象: 2.对象的特性 对象的两个重要特性是属性和方法。属性是与对象绑定的一组数据,可以只读、只写或者读写,使用时不加括号。例如,对于文件对象: 其.mode属性表示文件的打开模式: .closed属性表示文件是否关闭: 属性可以通过赋值修改: 属性的调用不需要用括号:

4.2 自定义类型

这节解决什么问题:这节要解决的不是背下“4.2 自定义类型”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“4.2 自定义类型”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 4.2 自定义类型 背后的对象模型、输入输出和适用边界。

在编程时,可以根据需要自定义一个新类型。自定义类型可以用关键字class,其基本形式为: 具体规律为: ●class关键字在最开始。 ●ClassName是自定义类型的名称,Python对类型名称没有规定,流行的做法是用 大骆驼拼写法 (Upper Camel Case),即每个单词的首字母大写,中间不留空格。 ●“()”中的ParentClass用来表示继承关系,可省略,默认为object。 ●“:”不能缺少,之后的内容要进行缩进。 ●三引号包含的部分是类型的文档(即docstring),可以省略。 ●类型的方法定义与函数定义类似,第一个参数表示是对象本身,通常用self表示。 例如,可以这样定义一个新类型Leaf表示树叶: 新类型Leaf继承了Python中最基本的类型,即object。 继承 (Inheritance)使一个类的对象可以直接使用另一个类的属性和方法,被继承的类叫作 父类 (Parent Class),如object;继承生成的类叫作 子类 (Child Class),如Leaf。子类Leaf可以看成是一个特殊的父类object。事实上,所有的对象都是一个object: 在Python中,除了object,基本类型还有int、float、long、bool、file、list、set、tuple、dict、frozenset等。这些基本类型的名称都是以小写字母开头的,名称的类型都是type: 这与类名Leaf的类型一致: 三引号的部分是对Leaf类的说明文档,可以调用Leaf的.__doc__属性查看: 说明文档通常是对该类型的解释说明。类型的帮助在IPython中可以通过问号查询: 对于Python内置的类型,可以通过在类型名后加上括号得到该类型的一个对象,如: 同理,可以

4.3 方法与属性

这节解决什么问题:这节要解决的不是背下“4.3 方法与属性”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“4.3 方法与属性”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 4.3 方法与属性 背后的对象模型、输入输出和适用边界。

自定义类型中通常要定义一些方法和属性。 1.直接添加属性 回顾之前对Leaf类的定义: 新属性可以用赋值的方式向对象中添加: 这样添加的新属性只对当前定义的对象有效,不能在新对象上使用: 2.添加普通方法 添加普通方法需要用def关键字定义。向Leaf类中添加一个新方法,表示树叶下落: 新方法.fall()接收两个参数,第一个是表示对象本身的self参数;第二个参数season表示季节,并有一个默认值“autumn”。生成一个新对象: 查看.fall()方法的帮助: 调用该方法时,self参数不用传入,会自动转换为对象leaf,因此只需要传入season参数。不带参数时,season用默认值: 传入season参数时: 3.函数中的特殊方法和特殊属性 除了.fall()方法,对象通常自带一些特殊的方法和属性。输入“leaf._”并按〈Tab〉键补全,会得到: 以下画线“__”开头的是一些特殊的方法或属性,常用的如下。 ●__init__():初始化对象。 ●__repr__():repr(obj)函数的返回值。 ●__str__():str(obj)函数的返回值。 ●__call__():调用obj()的返回值。

4.4 继承与复用

这节解决什么问题:这节要解决的不是背下“4.4 继承与复用”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“4.4 继承与复用”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 4.4 继承与复用 背后的对象模型、输入输出和适用边界。

在类的定义中: ParentClass是用来进行继承的,被继承的ParentClass是父类,定义的ClassName是子类。可以认为子类是一种特殊的父类。例如,假设父类是哺乳动物,人作为一个子类可以继承这个父类,因为人是哺乳动物的一种;狮子也可以继承哺乳动物,因为狮子也是哺乳动物的一种。 继承意味着子类拥有父类所有的方法和属性。例如,人是哺乳动物,从而人具有哺乳动物的属性和行为。同时,子类可以定义自己特殊的方法和属性。比如人有使用工具的能力,这是其他哺乳动物所不具有的。 1.类的继承 定义一个类Leaf: 定义一个子类枫树叶(MapleLeaf)来继承类Leaf,并在父类的基础上定义新方法.change_color(): 构造一个子类对象: 子类会继承父类的属性和方法,父类的属性和方法可以直接调用: 定义子类时,可以复用父类的构造函数: 调用子类中独有的特殊方法: 还可以对父类中已有的.fall()方法进行重定义: 在子类对象中,调用.fall()方法将改变树叶的颜色属性.color: 在子类中的修改不会影响父类中的方法。 2.super()函数 与父类的.fall()方法相比,子类的方法只增加了.change_color()的调用,之后的操作与父类的.fall()方法一致,代码存在冗余。为了解决这个问题,可以利用super()函数,在子类的.fall()方法中调用父类的.fall()方法。 通常的做法为: 因此,可以使用super(MapleLeaf,self)来调用父类的.fall()方法: super(MapleLeaf,self)返回的是与self绑定的一个父类Leaf对象:

4.5 公有、私有、特殊以及静态的方法与属性

这节解决什么问题:这节要解决的不是背下“4.5 公有、私有、特殊以及静态的方法与属性”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“4.5 公有、私有、特殊以及静态的方法与属性”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 4.5 公有、私有、特殊以及静态的方法与属性 背后的对象模型、输入输出和适用边界。

一些以“__”开头的都是对象的特殊方法和属性。通常来说: ●以字母开头都是公有的方法和属性,可以直接调用。 ●在Python中,“私有”的方法和属性以“__”开头,不过,并不存在真正私有的方法和属性,所谓“私有”只是不会被代码自动完成所记录,无法在按〈Tab〉键时自动补全。 ●以“__”开头并以“__”结尾的是一些系统内置的属性和方法。 ●以“__”开头不以“__”结尾的是一些更加特殊的方法,调用方式最为复杂。 ●装饰器@staticmethod可以生成一个静态方法,静态方法只有类本身能调用,类的对象不能调用,在定义时,静态方法不需要加self参数。 例如,定义一个具有以上属性和方法的类: 构造对象时调用了一个特殊的方法.__init__(): 查看公有属性和特殊属性: 公有方法: 私有方法: 以“__”开头不以“__”结尾的方法调用方式有所不同,需要加上类名: 静态方法可以用类去调用:

4.6 多重继承

这节解决什么问题:这节要解决的不是背下“4.6 多重继承”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“4.6 多重继承”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 4.6 多重继承 背后的对象模型、输入输出和适用边界。

多重继承 (Multiple Inheritance),指的是一个类可以同时从多个父类继承行为与特征的功能。Python支持多重继承,例如,可以将之前的Leaf类抽象为以下几类。 ●Leaf类:树叶,父类。 ●ColorChangingLeaf类:颜色可变的树叶,继承Leaf类。 ●DeciduousLeaf类:落叶类植物的树叶,继承Leaf类。 ●MapleLeaf类:枫叶,枫叶颜色可变,同时枫树是落叶类植物,可以让它同时继承ColorChangingLeaf类和DeciduousLeaf类。 各类的定义如下: 在定义多重继承时,只需要用逗号将多个父类隔开。MapleLeaf类只是简单地继承了两个类型。MapleLeaf类的对象可以使用两个父类的方法: 例如,从Leaf类继承而来的.color属性: 从ColorChangingLeaf类继承而来的.change()方法: 从DeciduousLeaf类继承而来的.fall()方法: 有时候多个父类可能会发生冲突。例如,可以在ColorChangingLeaf的定义中增加一个.fall()方法: 在两个父类的.fall()方法不同时,Python会优先使用定义在前的父类的方法。当ColorChangingLeaf类在前时,使用的是ColorChangingLeaf类的方法: 反过来,当DeciduousLeaf类在前时,使用的是DeciduousLeaf类的方法: 继承的顺序可以通过该类的.__mro__属性或.mro()方法来查看: 调用属性或方法时,会按照该顺序依次寻找,直到找到或者没有下一个父类为止。

4.7 本章学习笔记

这节解决什么问题:这节要解决的不是背下“4.7 本章学习笔记”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“4.7 本章学习笔记”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 4.7 本章学习笔记 背后的对象模型、输入输出和适用边界。

本章对Python面向对象编程进行了介绍。对读者来说,学习面向对象编程的一个重要作用是读懂相关的代码,因此,本章着重介绍了如何使用面向对象编程的语法,对于如何设计面向对象编程则不做介绍。 学完本章,读者应该做到: ●掌握对象的概念。 ●知道如何使用class关键字定义新类型。 ●知道如何定义使用对象的方法和属性。 ●知道一些特殊方法和属性的使用。 1.本章新术语 本章涉及的新术语见表4-1。 表4-1 本章涉及的新术语 2.本章新函数 本章涉及的新函数见表4-2。 表4-2 本章涉及的新函数 3.本章Python 2与Python 3的区别 本章不涉及Python 2与Python 3的区别。

辨析题:如果你只会照抄 第4章Python面向对象编程 里的例子,却无法换一个输入自己写出来,真正缺的是什么?

多数时候缺的不是记忆,而是对象模型、输入输出边界和操作顺序的理解。把知识点换到新输入上依然能运行,才算真的进入了自己的系统。