第十章 异常
Python使用被称为异常 的特殊对象,来管理程序执行期间发生的错误。
异常时使用try-expect代码块处理的。try-expect代码块让Python执行指定的操作,同时告诉Python发生异常时应该怎么办,即使出现异常程序也将继续运行。
1.处理ZeroDivisionError异常
2.使用try-expect代码块
print(5/0)
####
File "E:/A-桌面-Flies/Pycharm/practise1.py", line 1, in <module>
print(5/0)
ZeroDivisionError: division by zero
try:
print(5/0)
except ZeroDivisionError:
print('Can not divide by zero.')
######
Can not divide by zero.
可以看到使用异常,即使出现错误,显示的也是你编写好的友好的错误消息。而不是traceback。
3.使用异常避免崩溃
避免因输入错误,导致程序崩溃。
print("Please input 2 nums: ")
print("Enter 'q' to quit.")
while True:
first_num = input("first_num :")
if first_num == 'q':
break
second_num = input("second_num :")
if second_num == 'q':
break
answer = int(first_num) / int(second_num)
print(answer)
#########
first_num :4
second_num :0
Traceback (most recent call last):
File "E:/A-桌面-Flies/Pycharm/practise1.py", line 11, in <module>
answer = int(first_num) / int(second_num)
ZeroDivisionError: division by zero
可以看到这样非常不友好,输入错误的话就直接退出了。程序就直接崩溃了。
我们可以添加try-else代码块来避免这种情况。
print("Please input 2 nums: ")
print("Enter 'q' to quit.")
while True:
first_num = input("first_num :")
if first_num == 'q':
break
second_num = input("second_num :")
if second_num == 'q':
break
try:
answer = int(first_num) / int(second_num)
except ZeroDivisionError:
print('Can not divide by zero.')
else:#try成立时执行
print(answer)
######
Please input 2 nums:
Enter 'q' to quit.
first_num :4
second_num :0
Can not divide by zero.
first_num :4
second_num :1
4.0
4.处理FileNotFoundError异常
file_name = 'pip.txt'
with open(file_name) as obj:
contents = obj.read()
print(contents)
#####
Traceback (most recent call last):
File "E:/A-桌面-Flies/Pycharm/practise1.py", line 3, in <module>
with open(file_name) as obj:
FileNotFoundError: [Errno 2] No such file or directory: 'pip.txt'
file_name = 'pip.txt'
try:
with open(file_name) as obj:
contents = obj.read()
except FileNotFoundError:
msg = "Sorry, the file " + file_name + " does not exist."
print(msg)
#####
Sorry, the file pip.txt does not exist.
5.分析文本
split,分割字符串,生成一个列表。
file_name = 'alice.txt'
try:
with open(file_name) as obj:
contents = obj.read()
except FileNotFoundError:
msg = "Sorry, the file " + file_name + " does not exist."
print(msg)
else:
words = contents.split()
num_words = len(words)
print(words[:10])
print(f"{num_words}")
6.使用多个文本
def count_words(filename):
try:
with open(filename) as obj:
contents = obj.read()
except FileNotFoundError:
msg = "Sorry, the file " + filename + " does not exist."
print(msg)
else:
words = contents.split()
num_words = len(words)
print(f"{num_words}")
file_names = ['alice.txt', 'little women.txt']
for filename in file_names:
count_words(filename)
##########
201
60
7.失败是pass(不显示)
expect 执行 pass。它提醒你在程序的某个方什么都没有做。
def count_words(filename):
try:
with open(filename) as obj:
contents = obj.read()
except FileNotFoundError:
pass
else:
words = contents.split()
num_words = len(words)
print(f"{num_words}")
file_names = ['alice.txt', 'little women.txt', 'fuf.txt']
for filename in file_names:
count_words(filename)
#######
201
60
④存储数据
json模块让你能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。
1.使用json.dump()和json.load()
json.dump()结束两个实参:要存储的数据以及可用与存储数据的文件对象。
import json
num = [1, 5, 4, 6]
file_name = 'num.json'
with open(file_name, 'w') as f_obj:
json.dump(num, f_obj)
可以看到再Python的py路径下添加了一个后缀为。json的文件,其存储的数据为 [1, 5, 4, 6] 。
json.load()将这个列表读取到内存中
import json
file_name = 'num.json'
with open(file_name) as f_obj:
num = json.load(f_obj)
print(num)
#####
[1, 5, 4, 6]
2.保存和读取用户生成的数据
import json
user_name = input("What's your name?")
file_name = 'username.json'
with open(file_name, 'w') as f_obj:
json.dump(user_name, f_obj)
print("Remeber!" + user_name)
#####
What's your name?snamead
Remeber!snamead
这个名字已经被保存到了文件中,下面再使用json.load读取变量user_name。
import json
file_name = 'username.json'
with open(file_name) as f_obj:
user_name = json.load(f_obj)
print("Hello!" + user_name)
####
Hello!snamead
将上述两个代码合并。
import json
file_name = 'username.json'
try:
with open(file_name) as f_obj:
user_name = json.load(f_obj)
except FileNotFoundError:
user_name = input("What's your name?")
with open(file_name, 'w') as f_obj:
json.dump(user_name, f_obj)
print("Remember!" + user_name)
else:
print("Hello!" + user_name)
若是第一次运行 (没有创立json文件) 则创立并输入姓名。
若是第二次运行,则打印 语句。
3.重构
将代码划分为一系列完成具体工作的函数。这个给过程称为重构。
可将上述代码重构。
import json
def greet_user():
file_name = 'username.json'
try:
with open(file_name) as f_obj:
user_name = json.load(f_obj)
except FileNotFoundError:
user_name = input("What's your name?")
with open(file_name, 'w') as f_obj:
json.dump(user_name, f_obj)
print("Remember!" + user_name)
else:
print("Hello!" + user_name)
greet_user()
可以看到什么都没有动,只是把前面的一个程序给封装了起来。
下面这个例子,建议好好理解,看看在.json文件是否存在的前提下,分别运行什么状态。
import json#引用json库
def get_stored_user_name():#得到存储的名称
file_name = 'username.json'#文件名的定义
try:
with open(file_name) as f_obj:#打开文件
user_name = json.load(f_obj)
except:#
return None#没有的话返回None
else:
return user_name#成功获取用户名
def greet_user():
user_name = get_stored_user_name()
if user_name:#得到用户名
print("Welcome, " + user_name + '.')
else:#None,即事先没有名字
user_name = input("What's your name?")
file_name = 'username.json'
with open(file_name, 'w') as f_obj:
json.dump(user_name, f_obj)
print("Remember!" + user_name)
greet_user()
终极版:
import json
def get_stored_user_name():
file_name = 'username.json'
try:
with open(file_name) as f_obj:
user_name = json.load(f_obj)
except:
return None
else:
return user_name
def get_new_name():#输入新的名字
user_name = input("What's your name?")#提示输入
file_name = 'username.json'#文件名定义
with open(file_name, 'w') as f_obj:#打开,写文件名
json.dump(user_name, f_obj)#在这个文件里写use_name
return user_name#返回名字
def greet_user():
user_name = get_stored_user_name()
if user_name:#已经有名字
print("Welcome, " + user_name + '.')
else:#无名字
user_name = get_new_name()#调用函数,得到名字
print("Remember!" + user_name)
greet_user()
重构的方法确实提高了代码的模块化,使代码更清晰,便于维护。