学习目标:
01_异常
学习目标:
1.1 异常简介
- 程序在运行期间,当 Python 检测到一个错误时,解释器就无法继续执行(俗称:程序崩溃)了,反而出现了一些错误的提示,这就是所谓的"异常"
- 注意:?异常不是语法错误,语法错误,是程序写错了,异常是指程序已经运行后的非语法错误
异常示例代码:
print('='*20)
# 如果'xxx.txt'文件不存在,只读方法打开
# 解释器检查到异常错误,默认动作程序终止运行(崩溃)
open('xxx.txt', 'r')
print('*'*20)
运行结果:
说明:
- 只读方式打开一个不存在的文件
xxx.txt ,就会抛出给我们一个FileNotFoundError 类型的错误
1.2 常见内置异常演示
# FileNotFoundError: [Errno 2] No such file or directory: 'xxx.txt'
# open('xxx.txt', 'r')
# 只写方式打开文件,然后读取文件内容
f = open('yyy.txt', 'w')
# io.UnsupportedOperation: not readable
# f.read()
# 输入一个数,类型为字符串,然后做判断
# TypeError: '>' not supported between instances of 'str' and 'int'
# age = input('请输入年龄:')
# if age > 18:
# print('成年了')
# 10/0,被除数不能是0
# ZeroDivisionError: division by zero
10/0
02_捕获异常
学习目标:
- 知道处理异常的目的
- 掌握捕获异常的相关操作:try…except…else…finally
2.1 处理异常目的
- 只要解释器检查到异常错误,默认执行的动作是终止程序
- 处理异常目的:防止程序退出,保证程序正常执行
2.2 捕获异常
2.2.1 try...except...
语法格式:
try:
可能发生异常的代码
except:
# 处理异常的代码
示例代码:
try:
print('=' * 20)
open('xxx.txt', 'r') # 发生了异常,自动跳转到except里面
print('=' * 20)
except:
print('try里面发生了异常')
运行结果:
====================
try里面发生了异常
2.2.2 捕获指定异常类型
语法格式:
try:
可能发生异常的代码
except 异常类型:
处理异常的代码
示例代码:
try:
print('=' * 20)
open('xxx.txt', 'r') # 发生了异常,自动跳转到except里面
print('=' * 20)
except FileNotFoundError:
print('try里面发生了异常')
运行结果:
====================
try里面发生了异常
2.2.3 except捕获多个异常
语法格式:
try:
可能发生异常的代码
except (异常类型1, 异常类型2):
处理异常的代码
示例代码:
try:
print('=' * 20)
# open('xxx.txt', 'r')
print('=' * 20)
print(num)
print('=' * 20)
except (FileNotFoundError, NameError):
print('try里面发生了异常')
2.2.4 获取异常的信息描述
语法格式:
"""
try:
可能发生异常的代码
except 异常类型 as 异常对象名:
print(异常对象名) 即可获取异常的信息描述
"""
示例代码:
try:
print('=' * 20)
open('xxx.txt', 'r')
print('=' * 20)
except FileNotFoundError as e:
print('异常信息为:', e)
运行结果:
====================
异常信息为: [Errno 2] No such file or directory: 'xxx.txt'
2.2.5 捕获任意类型的异常
语法格式:
"""
try:
可能发生异常的代码
except Exception as 异常对象名:
Exception 为异常类的父类
"""
示例代码:
try:
print('=' * 20)
open('xxx.txt', 'r')
print('=' * 20)
# except Exception: 捕获任意异常的类型
except Exception as e:
print('异常信息为:', e)
2.2.6 异常中else
- 在 if 中,它的作用是当条件不满足时执行的实行
- 同样在 try...except... 中也是如此,即如果没有捕获到异常,那么就执行else中的事情
语法格式:
"""
try:
可能发生异常的代码
except:
处理异常的代码
else:
没有发生异常,except不满足执行else
"""
示例代码:
try:
num = 100
print(num)
except NameError as errorMsg:
print('产生错误了:%s'%errorMsg)
else:
print('没有捕获到异常,真高兴')
运行结果:
====================
666
====================
没有发生异常,很开心
2.2.7 try...finally...
(1)语法格式
语法格式:
"""
try:
可能发生异常的代码
except:
处理异常的代码
else:
没有发生异常,except不满足执行else
finally:
不管有没有异常,最终都要执行
"""
示例代码:
try:
print('=' * 20)
# num = 666
print(num)
print('=' * 20)
except Exception as e:
print('异常信息为:', e)
else:
print('没有发生异常,很开心')
finally:
print('不管有没有异常,最终都要执行')
运行结果:
====================
异常信息为: name 'num' is not defined
不管有没有异常,最终都要执行
(2)应用场景
- 对于文件操作,在文件打开的前提下,后面文件的其它操作,不管有没有发生异常,最终都应该关闭文件
f = open('yyy.txt', 'w') # 前提是,成功打开文件
try:
# ret = f.read()
# print(ret)
f.write('hello mike')
print('='*20)
except Exception as e:
print('产出异常,异常信息为:', e)
else:
print('没有产生异常')
finally:
print('不管有没有异常,都要关闭文件')
f.close()
03_异常传递
学习目标:
3.1 异常传递特点
- 如果异常在内部产生,如果内部不捕获处理,这个异常会向外部传递
3.2 异常嵌套
- try嵌套时,如果内层try没有捕获处理该异常,就会向外层try进行传递
try:
f = open('yyy.txt', 'w')
# 内部语句执行完,才向外部传递异常
try:
# 前面只写方式打开文件,不能读文件,产生异常
# 内部没有捕获处理异常
ret = f.read()
print(ret)
finally:
print('关闭文件')
f.close()
except Exception as e:
print('外层捕获异常:', e)
运行结果:
关闭文件
外层捕获异常: not readable
3.3 函数嵌套
- 函数嵌套时,如果内层函数没有捕获处理该异常,就会向外层函数进行传递
# 定义1个函数,函数内部发生了异常 test01(),没有捕获处理
def test01():
print('开始执行test0111111')
print(num)
print('结束执行test0111111')
# 定义另外一个函数 test02, 在函数内部调用test01
def test02():
print('开始执行test02222222')
test01()
print('结束执行test02222222')
# 定义一个test03函数,函数内部调用test01,但是对test01做异常处理
def test03():
print('开始执行test0333333')
try:
test01()
except Exception as e:
print('外层函数捕获异常:', e)
print('结束执行test0333333')
# 调用test02()
# test02()
test03()
运行结果:
开始执行test0333333
开始执行test0111111
外层函数捕获异常: name 'num' is not defined
结束执行test0333333
04_自定义异常
学习目标:
抛出自定义的异常
- 用户可用 raise语句 来人为抛出一个异常。
- 异常/错误对象必须有一个名字,且它们应是Exception类的子类
语法格式:
# 1. 自定义异常类
class 自定义异常类名字(Exception):
1.1 重新写__init__(self, 形参1, 形参2,……)
# 建议调用父类的init,先做父类的初始化工作
super().__init__()
咱们自己写的代码
1.2 重新写__str__(),返回提示信息
# 2. 抛出异常类
raise 自定义异常类名字(实参1, 实参2,……)
示例代码:
"""
需求:
1. 自定义异常类,电话号码长度异常类
1.1 __init__,添加2个属性,用户电话的长度,要求的长度
1.2 __str__ 返回提示描述意思,如:用户电话长度为:xx位, 这边要求长度为:11位
2. 只要用户输入的手机号码不为11位,抛出自定义异常类
"""
# 1. 自定义异常类,电话号码长度异常类
class NumberError(Exception):
"""自定义异常类,电话号码长度异常类"""
# 添加2个属性,用户电话的长度,要求的长度
def __init__(self, _user_len, _match_len=11):
super().__init__() # 调用父类的init
self.user_len = _user_len # 用户电话的长度
self.match_len = _match_len # 要求号码的长度
def __str__(self):
return f'用户电话长度为:{self.user_len} 位, 这边要求的长度为:{self.match_len} 位'
# 2. 只要用户输入的手机号码不为11位,抛出自定义异常类
try:
num_str = input('请输入你的号码:')
if len(num_str) != 11:
raise NumberError(len(num_str)) # 抛出自定义异常类
except NumberError as e: # e 为 NumberError(len(num_str))实例对象 的别名
print('异常信息为:', e)
运行结果:
请输入你的号码:11232
异常信息为: 用户电话长度为:5 位, 这边要求的长度为:11 位
05_模块
学习目标:
- 知道import和from...import...导入模块区别
- 知道import...as...能够给导入的模块取别名
- 知道模块搜索路径保存在sys.path变量中
5.1 模块介绍
- 模块是一个由Python代码组成的文件,就是一个以
.py 结尾的文件。 - 模块包含函数、类和变量,还可以包括可运行的代码。
- 模块的主要作用:
- 提高了代码的可维护性
- 一个模块编写完毕之后,其他模块直接调用,不用再从零开始写代码了,节约了工作时间
- 避免名字冲突
5.2 模块的导入
5.2.1 import
语法格式:
"""
导入格式: import 模块名
使用格式: 模块名.函数 模块名.类名 模块名.变量名
"""
示例代码:
# 导入模块
import random
# 模块名.函数
num = random.randint(1, 3)
print(num)
# 模块名.类名
# 创建对象
ran = random.Random()
print(type(ran))
# 模块名.变量名
print(random.TWOPI)
5.2.2 from…import导入模块中需要的内容
- from…import可以只导入模块中需要使用的内容
语法格式:
"""
导入格式: from 模块名 import 需使用的函数、类、变量
使用格式: 函数、类、变量 无需通过模块名引用
"""
示例代码:
from random import randint, Random, TWOPI
# 函数
num = randint(1, 3)
print(num)
# 类
ran = Random()
print(type(ran))
# 变量
print(TWOPI)
5.2.3 from…import导入模块中所有的内容
语法格式:
"""
导入格式: from 模块名 import *
使用格式: 函数、类、变量 无需通过模块名引用
"""
示例代码:
from random import *
# 函数
num = randint(1, 3)
print(num)
# 类
ran = Random()
print(type(ran))
5.2.4 import...as...给导入的模块取别名
- 把复杂名字改简单些
- 把已经同名的名字改一个不同名的名字
语法格式:
"""
模块起别名
导入格式:import 模块 as 模块别名
使用格式:模块别名.工具(工具指函数、类、变量)
模块工具起别名
导入格式:from 模块 import 工具 as 工具别名
使用格式:工具别名 无需通过模块名引用
"""
示例代码:
# 将模块random取别名为r
import random as r
# 模块别名.方法
num = r.randint(1, 3)
print(num)
# 模块工具randint取别名为ri
from random import randint as ri
num = ri(1, 3)
print(num)
5.2.5 模块搜索路径
当你导入一个模块,Python解析器对模块位置的搜索顺序是:
- 当前目录
- 如果不在当前目录,Python则搜索系统路劲
- 模块搜索路径存储在system模块的sys.path变量中。
示例代码:
import sys
# 模块搜索路径存储在system模块的sys.path变量中
print(sys.path)
06_模块制作
学习目标:
- 知道如何制作自定义模块
- 知道模块中
__name__ 的作用 - 知道使用from...import*时
__all__ 在模块中的作用
6.1 定义自己的模块
在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。比如有这样一个文件module.py ,在module.py 中定义了所需的函数:
def my_add(a, b):
"""返回2个数相加结果"""
return a+b
def my_sub(a, b):
"""返回2个数相减结果"""
return a-b
6.2 调用自己定义的模块
import module # 导入模块
# 调用模块中的函数
ret = module.my_add(1, 1)
print(ret)
ret = module.my_sub(10, 20)
print(ret)
6.3 测试模块
6.3.1 测试模块
在实际开中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在模块文件中添加一些测试信息,例如:
module.py:
def my_add(a, b):
"""返回2个数相加结果"""
return a+b
def my_sub(a, b):
"""返回2个数相减结果"""
return a-b
ret = my_add(2, 2)
print('模块中测试代码:my_add(2, 2) = ', ret)
ret = my_sub(10, 2)
print('模块中测试代码:my_sub(10, 2) = ', ret)
导入模块文件,默认执行模块文件的内容:
说明:
- 模块文件,应该是单独执行时,才执行其测试代码
- 导入模块文件时,不应该执行测试代码
- Python中变量
__name__ 能解决上述问题
6.3.2 模块中的__name__
- 直接运行此文件,
__name__ 的结果为__main__ - 此文件被当做模块文件导入时,
__name__ 的结果不为__main__
- ?如果不想导包把模块的测试代码也运行,把模块的测试代码放在
if __name__ == '__main__': 条件语句里面
6.4 模块中的__all__
-
模块中__all__ 变量,只对from xxx import * 这种导入方式有效 -
模块中__all__ 变量包含的元素,才能会被from xxx import * 导入 -
__all__ 格式: __all__ = ['变量名', '类名', '函数名', ……]
|