异常
异常介绍?
- 程序的错误有两种
- 代码错误
- 代码正常, 运行的时候报错, 这个叫异常
# prnit("hello world") # 代码错误
a = int(input("请输入一个整数")) # 代码正确 ,但运行的时候, 如果用户输入的不是数字, 会报错
- 程序不应该因为异常而非法终止, 发生异常的时候, 程序是可控的
捕捉异常
- 发生异常, 如果不捕捉, 程序会因为异常而意外报错终止
- 一个异常一旦被捕捉到, 那么就不会因为异常而报错终止了
try:
可能产生异常的代码
except:
发生异常会执行的代码, 如果没有异常, 这里的代码不会执行
try:
a = int(input("请输入一个整数"))
except:
print("输入的数字非法")
try:
a = int(input("请输入一个整数")) # 如果这里就发生异常, 下面两句话都不执行, 直接跳转到except下面
b = int(input("请输入一个整数"))
print(a / b)
except:
print("异常发生")
捕获指定异常
try:
可能发生异常的代码
except 异常类型1:
发生异常类型1要执行的代码
except 异常类型2:
发生异常类型2要执行的代码
except 异常类型n:
发生异常类型n要执行的代码
try:
a = int(input("请输入一个整数")) # 如果这里就发生异常, 下面两句话都不执行, 直接跳转到except下面
b = int(input("请输入一个整数"))
print(a / b)
except ValueError:
print("请输入正确的整数")
except ZeroDivisionError:
print("除数不能为0")
'''
ValueError 值错误异常
ZeroDivisionError 除数为0的异常
'''
捕捉未知异常
try:
可能发生异常的语句
except Exception as e: # e相当于一个变量e,用来捕捉异常的描述
发生要执行代码, 如果要想显示异常描述, 可以用print把e的内容输出
try:
a = int(input("请输入一个整数")) # 如果这里就发生异常, 下面两句话都不执行, 直接跳转到except下面
b = int(input("请输入一个整数"))
print(a / b)
except Exception as e:
print(f"异常发生:{e}")
捕获指定异常与捕获未知异常
try:
a = int(input("请输入一个整数")) # 如果这里就发生异常, 下面两句话都不执行, 直接跳转到except下面
b = int(input("请输入一个整数"))
print(a / b)
except ValueError:
print("请输入正确的整数")
except ZeroDivisionError:
print("除数不能为0")
except Exception as e:
print(f"未知异常{e}")
捕捉异常的完整语句
try:
可能发生异常的代码
except 异常类型1:
发生异常类型1执行的代码
except 异常类型n:
发生异常类型n执行的代码
except Exception as e:
发生未知异常执行的代码
else:
没有发生异常执行的代码
finally:
无论是否有异常, 都要执行的代码
try:
a = int(input("请输入一个整数")) # 如果这里就发生异常, 下面两句话都不执行, 直接跳转到except下面
b = int(input("请输入一个整数"))
print(a / b)
except ValueError:
print("请输入正确的整数")
except ZeroDivisionError:
print("除数不能为0")
except Exception as e:
print(f"未知异常{e}")
else: # 没有异常发生执行的代码
print("没有任何异常发生") # 有异常发生, 这个代码不会执行
finally:
print("无论是否有异常, 都会执行的代码")
异常的传递
- 一个函数内部代码发生异常, 如果函数内部没有用try捕捉这个异常, 这个异常会传递给函数的调用者
- 函数内部的异常, 函数的调用者也可以捕捉
- 函数内部的异常, 所有的调用者如果都没有捕捉,最后会导致异常出错终止
class A:
def my_func1(self):
try:
print(1 / 0)
except:
print("异常发生")
def my_func2(self):
self.my_func1()
a = A()
a.my_func2()
# ############################
class A:
def my_func1(self): # 调用my_func1会把异常给到调用者
print(1 / 0)
def my_func2(self):
try:
self.my_func1() # 在调用者里面捕捉异常
except:
print("异常发生")
a = A()
a.my_func2()
# ############################
class A:
def my_func1(self): #
print(1 / 0) # 发生异常, 把异常给了调用者
def my_func2(self):
self.my_func1() # 由于my_func1发生异常, 但调用者没捕捉, 异常给了my_func2的调用者
a = A()
try:
a.my_func2() # 由于my_func1和my_func2里面都没捕捉异常, 所以这里需要捕捉, 不然代码异常出错
except:
print("异常发生")
抛出异常
raise Exception("异常的描述")
- 使用raise代码自己抛出的异常, 如果不用try捕捉, 同样会异常报错终止
try:
raise Exception("自己抛出的异常")
except Exception as e:
print(f"发生异常, 异常的描述为{e}")
# 如果密码为"123456", 提示正确, 否则提示错误
'''
password = input("请输入密码")
if password == "123456":
print("正确")
else:
print("错误")
'''
password = input("请输入密码")
try:
if password != "123456":
raise Exception("错误")
except Exception as e:
print(e)
else:
print("正确")
案例-判断手机号码格式是否正确
'''
用户输入手机号码, 判断号码是否正确
手机号码规则
1 纯数字组成
2 长度11位
3 第一位是1
4 第二位大于2
如果收入的手机号码格式正确, 显示正确, 如果不正确显示具体的错误原因
'''
mobile = input("请输入手机号码")
try:
int(mobile)
if len(mobile) != 11:
raise Exception("手机号码必须是11位")
if mobile[0] != "1":
raise Exception("手机号码第一位必须为1")
if int(mobile[1]) <= 2:
raise Exception("手机号码第二位必须大于2")
except ValueError:
print("手机号码必须为纯数字组成")
except Exception as e:
print(e)
else:
print("手机号码格式正确")
文件读写
文件的类型
- 文本文件
- 二进制文件
- 只要不是文本文件, 就是二进制文件
- 各种图像, 声音, 还有各种可执行程序都是二进制
操作文件的步骤
一个读文件的例子
# 第一步: 打开文件
file = open(r"c:\file\a.txt", "r") # file是open返回的一个文件对象, 第一个参数是打开的文件名和路径, 第二个参数"r"
# 第二步: 把文件内容读取到一个变量中
txt = file.read() # 调用file对象的read方法读文件内容, 把读取到的内容放入变量txt中
# 第三步: 关闭文件
file.close() # 调用file对象的close方法,关闭文件
print(txt) # 显示变量txt的值
- 读文件的时候看到异常UnicodeDecodeError, 代表不知道文件的字符集是什么, 所以读取不到内容
读取带有中文的文件
- open打开文件的时候, 要指定文件的字符集
- 常见的中文字符集
file = open("文件路径文件名", "r", encoding="utf-8")
# 第一步: 打开文件
# 如果要读写 的文件和要执行py文件在同一个目录里, 那么open就不用写路径, 直接写文件名即可
file = open(r"03-异常.py", "r", encoding="utf-8") # file是open返回的一个文件对象, 第一个参数是打开的文件名和路径, 第二个参数"r"
# 第二步: 把文件内容读取到一个变量中
txt = file.read() # 调用file对象的read方法读文件内容, 把读取到的内容放入变量txt中
# 第三步: 关闭文件
file.close() # 调用file对象的close方法,关闭文件
print(txt) # 显示变量txt的值
file = open(r"c:\file\b.txt", "r", encoding="gbk")
# 第二步: 把文件内容读取到一个变量中
txt = file.read()
# 第三步: 关闭文件
file.close() #
print(txt) # 显示变量txt的值
- read的功能是, 执行一次, 就把文件所有的内容读取到一个变量中
readline按行读取文件内容
- 调用readline一次读一行
- 第二次调用readline自动会读取文件的下一行
- 如果已经读取到文件最后readline返回""
file = open(r"c:\file\c.txt", "r", encoding="gbk")
while True:
txt = file.readline()
if txt == "": # 如果调用readline返回的结果是"", 代表已经读取到文件最后了, 没内容了
break
print(txt, end="")
file.close()
file = open(r"c:\file\c.txt", "r", encoding="gbk")
line_num = 1 # 行号人类习惯, 从1开始
while True:
txt = file.readline()
if txt == "": # 如果调用readline返回的结果是"", 代表已经读取到文件最后了, 没内容了
break
print(f"{line_num}:\t{txt}", end="")
line_num += 1
file.close()
写文件
# 第一步:打开文件
file = open(r"c:\file\d.txt", "w", encoding="gbk")
# 第二步: 写入文件内容
file.write("hello world")
# 第三步: 关闭文件
file.close()
# 检查file目录下是否有文件d.txt, 打开文件d.txt查看内容
"w"
- write的首字母, 写文件 如果目标文件不存在, 新建一个文件, 如果目标文件存在, 就覆盖已有内容
"a"
- append的首字母, 追加写文件, 如果目标文件不存在, 新建一个文件, 如果目标文件存在, 在已有内容后面追加内容
file = open(r"c:\file\a.txt", "a", encoding="gbk") #"a"的意思是追加写
file.write("是的冯绍峰的是发\n")
file.close()
open打开文件的几种模式
"r"
- 读文本文件---- 读取的文件一定要存在, 否则会抛出异常FileNotFoundError
- 一个文件用r打开, 就只能读, 不能写入内容
"w"
- 写文本文件 ---- 如果文件不存在, 创建新文件, 如果文件存在, 覆盖已有文件内容
- 一个文件用w打开, 就只能写, 不能读取内容
"a"
- 追加写文件 ----- 如果文件不存在, 创建新文件, 如果文件存在, 在已有内容后面追加
- 一个文件用a打开, 就只能写, 不能读取内容
"rb"
"wb"
"ab"
读写文件的注意项
- 以读方式打开的文件, 不能写入内容
- 以写方式打开的文件, 不能读取内容
- 下面的两个代码案例, 都是错误的
'''
file = open(r"c:\file\a.txt", "r", encoding="gbk")
file.write("aaaaaaa") # r方式打开的文件, 只能读取内容
file.close()
'''
'''
file = open(r"c:\file\a.txt", "w", encoding="gbk")
txt = file.read() # w方式打开的文件, 只能写入内容
file.close()
'''
总结