内容正文:
第9章 面向对象编程
1
学习目标/Target
了解面向对象,能够区分面向过程和基于面向对象的编程思想
了解面向对象的特性,能够说出什么是封装、继承、多态
熟悉对象和类的关系,能够归纳出对象和类的关系
掌握类的定义和对象的创建方式,能够通过关键字class定义类并创建对象
掌握属性,能够在程序中正确访问和修改类属性、实例属性和私有属性
2
学习目标/Target
掌握方法,能够在程序中正确调用实例方法、类方法、静态方法和私有方法
掌握构造方法的使用方式,能够在构造方法中初始化实例属性
掌握封装的特性,能够在程序中实现类的封装
掌握单继承、多继承的语法,能够在类中实现单继承和多继承
掌握重写的方式,能够在子类中实现父类方法的重写
3
学习目标/Target
掌握super()函数的使用方式,能够通过super()函数调用父类中被重写
的方法
掌握多态的特性,能够在程序中以多态的形式调用类中定义的方法
了解异常,能够说出异常的类型以及常见的异常类
掌握捕获与处理异常的方式,能够选择合适的方式捕获与处理异常
掌握抛出异常方式,能够通过raise和assert语句抛出异常
4
章节概述/ Summary
面向对象是程序开发领域的重要思想,它以模拟人类认识客观世界的方式来看待程序中的事务,将这些事务皆视为对象。Python是一种支持面向对象编程的语言,Python3.x版本的源码是完全基于面向对象的思想设计的。因此,了解面向对象的思想对于学习Python编程非常重要。本章将针对面向对象编程的相关知识进行详细地讲解。
5
目录/Contents
01
面向对象概述
类与对象
属性
02
03
方法
04
构造方法
05
6
目录/Contents
06
实例:航天器信息查询工具
封装
继承
07
08
多态
09
异常
10
7
多态
9.9
8
9.9 多态
多态是面向对象编程的重要特性之一,它的直接表现即让不同类的同一功能可以通过同一个接口调用,表现出不同的行为。
9.9 多态
定义一个表示猫的类Cat和一个表示狗的类Dog,这两个类都包含shout()方法,代码如下:
class Cat:
def shout(self):
print("喵喵喵~")
class Dog:
def shout(self):
print("汪汪汪!")
定义一个函数test(),该函数需要接收一个参数obj,并在其内部让obj调用了shout()方法,示例代码如下。
def test(obj):
obj.shout()
cat = Cat()
dog = Dog()
test(cat)
test(dog)
异常
9.10
11
9.10.1 异常概述
Python中程序执行时检测到的错误称为异常。例如,两个数相除时把0作为除数进行运算,此时便会引发程序出现异常,代码如下:
print(1 / 0)
运行代码,结果如下所示:
Traceback (most recent call last):
File "D:\PythonProject\Chapter09\test.py", line 1, in <module>
print(1 / 0)
~~^~~
ZeroDivisionError: division by zero
9.10.1 异常概述
1. NameError
NameError是程序中使用了未定义的变量时会引发的异常。例如,访问一个未定义过的变量name,代码如下:
print(name)
运行代码,结果如下所示:
Traceback (most recent call last):
File "D:\PythonProject\Chapter09\test.py", line 1, in <module>
print(name)
^^^^
NameError: name 'name' is not defined
9.10.1 异常概述
IndexError是程序越界访问时引发的异常。例如,列表list_demo中有4个元素,使用索引访问列表中第5个元素,代码如下:
运行代码,结果如下所示:
list_demo = [1, 2, 3, 4]
print(list_demo[4])
Traceback (most recent call last):
File "D:\PythonProject\Chapter09\test.py", line 2, in <module>
print(list_demo[4])
~~~~~~~~~^^^
IndexError: list index out of range
2. IndexError
9.10.1 异常概述
运行代码,结果如下所示:
AttributeError是使用对象访问不存在的属性引发的异常。例如,定义一个没有任何属性和方法的类Dog,通过Dog类的对象访问不存在的属性name,代码如下:
class Dog:
pass
dog = Dog()
print(dog.name)
Traceback (most recent call last):
File "D:\PythonProject\Chapter09\test.py", line 4, in <module>
print(dog.name)
^^^^^^^^
AttributeError: 'Dog' object has no attribute 'name'
3. AttributeError
9.10.1 异常概述
FileNotFoundError是未找到指定文件或目录时引发的异常。例如,打开一个本地不存在的文件,代码如下:
file = open("test.txt")
运行代码,结果如下所示:
Traceback (most recent call last):
File "D:\PythonProject\Chapter09\test.py", line 1, in <module>
file = open("test.txt")
^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'
4. FileNotFoundError
9.10.2 捕获与处理异常
Python提供了try-except-else-finally语句来捕获与处理异常,try-except-else-finally语句的基本语法格式如下。
try:
可能发生异常的代码
except [异常类 [as 变量名]]:
捕获异常后的处理代码
else:
没有发生异常的处理代码
finally:
无论是否发生异常都执行的代码
9.10.2 捕获与处理异常
except子句用于捕获并处理异常,它可以省略异常类,也可以指定异常类。若指定了异常类,则只有匹配该类的异常会被捕获与处理。另外,except子句还可以使用as关键字,用于将捕获到的异常信息赋值给一个变量,便于输出异常信息。
else子句的代码只会在try子句没有发生任何异常时被执行。
finally子句的代码始终会被执行,无论try子句是否发生异常。
9.10.2 捕获与处理异常
当程序执行try-except-else-finally语句时,会按照以下过程捕获与处理异常:
(1)执行try子句的代码。
(2)根据try子句的代码是否发生异常分以下情况执行:
① 若try子句的代码没有发生异常,则跳过except子句的代码,执行else子句的代码。
② 若try子句的代码发生异常,则跳过try子句中未执行的代码,确认except子句是否能捕获异常。若能捕获则执行except子句的代码;若不能捕获则跳过except子句的代码,执行else子句的代码。
(3)执行finally子句的代码。
9.10.2 捕获与处理异常
1. 捕获单个异常
捕获单个异常的方式比较简单,只需要在关键字except之后指定要捕获的单个异常类即可,示例如下:
num_one = int(input("被除数:"))
num_two = int(input("除数:"))
try:
print("商:", num_one / num_two)
except ZeroDivisionError:
print("出错了")
9.10.2 捕获与处理异常
在异常类之后使用关键字as,通过该关键字获取异常的具体信息,具体代码如下。
num_one = int(input("被除数:"))
num_two = int(input("除数:"))
try:
print("商:", num_one / num_two)
except ZeroDivisionError as error:
print("出错了")
1. 捕获单个异常
9.10.2 捕获与处理异常
捕获多个异常的实现方式比较多样,既可以通过多个except子句完成,也可以通过一个except子句完成。若通过一个except子句完成,则需要在关键字except之后以元组形式指定多个异常类,示例如下:
try:
num_one = int(input("被除数:"))
num_two = int(input("除数:"))
print("商:", num_one / num_two)
except (ZeroDivisionError, ValueError) as error:
print("出错了,原因:", error)
2. 捕获多个异常
9.10.2 捕获与处理异常
捕获全部异常的方式有两种,一种方式是将关键字except之后的异常类设置为Exception,另一种方式是省略关键字except后面的内容。例如,使用第一种方式捕获全部异常,代码如下:
try:
num_one = int(input("被除数:"))
num_two = int(input("除数:"))
print("商:", num_one / num_two)
except Exception as error:
print("出错了,原因:", error)
3. 捕获全部异常
9.10.2 捕获与处理异常
若try子句没有发生异常,程序会执行else子句后的代码。示例如下:
try:
num_one = int(input("被除数:"))
num_two = int(input("除数:"))
result = num_one / num_two
except Exception as error:
print("出错了,原因:", error)
else:
print("商:", result)
4. 没有发生异常
9.10.2 捕获与处理异常
无论try子句是否发生异常,finally子句后的代码都要执行。基于finally子句的特性,实际开发中finally 子句多用于预设资源的清理操作,如关闭文件、关闭网络连接、关闭数据库连接等。
5. 产生异常的资源清理
9.10.2 捕获与处理异常
在使用Python处理文件时,为避免打开的文件占用过多的系统资源,需要在完成对文件的操作后及时使用close()方法关闭文件。为了避免程序发生异常时无法关闭文件,可以将文件关闭操作放在finally子句中,示例如下:
file = open('test.txt', 'r')
try:
file.write("人生苦短,我用Python")
except Exception as error:
print("写入文件失败", error)
finally:
file.close()
print('文件已关闭')
5. 产生异常的资源清理
9.10.3 抛出异常
Python使用raise语句可以显式地抛出异常,reise语句的用法如下:
raise 异常类 # 方式1:使用异常类名引发指定的异常
raise 异常类对象 # 方式2:使用异常类的对象引发指定的异常
raise # 方式3:使用刚出现过的异常重新引发异常
第1种方式和第2种方式是对等的,都会引发指定类型的异常,其中第1种方式会隐式创建一个该异常类型的对象,第2种方式是最常见的,它会直接提供一个该异常类型的对象;第3种方式用于重新引发刚刚发生的异常。
1. 使用raise语句抛出异常
9.10.3 抛出异常
raise IndexError
raise IndexError()
raise IndexError('索引下标超出范围') # 抛出异常及其具体信息
raise
使用raise语句抛出异常的示例如下:
1. 使用raise语句抛出异常
9.10.3 抛出异常
assert语句又称为断言语句,其语法格式如下所示:
assert表达式[, 异常信息]
以上语法格式的assert后面紧跟一个表达式,表达式的值为False时触发AssertionError异常,值为True时不做任何操作;表达式之后可以使用字符串来描述异常信息。
2. 使用assert语句抛出异常
9.10.3 抛出异常
assert语句可以帮助程序开发者在开发阶段调试程序,以保证程序能够正确运行。接下来,使用断言语句判断用户输入的除数是否为0,示例代码如下:
num_one = int(input("被除数:"))
num_two = int(input("除数:"))
assert num_two != 0, '除数不能为0' # assert语句判定num_two不等于0
result = num_one / num_two
print(num_one, '/', num_two, '=', result)
2. 使用assert语句抛出异常
本章小结
本章主要讲解了面向对象编程的相关知识,包括面向对象概述、类与对象、属性、方法构造方法、封装、继承、多态以及异常。通过本章的学习,读者能理解面向对象的思想与特性,掌握面向对象的编程技巧,为以后的开发奠定扎实的面向对象编程基础。
本
章
小
结
31
$$