10.文件和异常
文件和异常
从文件中读取数据
要使用文本文件中的信息,首先需要将信息读取到内存中
pi_digits.txt
3.1415926535 8979323846 2643383279
file_reader.py
with open('pi_digits.txt') as file_object: contents = file_object.read() print(contents.rstrip())
函数open()返回一个表示文件的对象
也可以调用open()和close()来打开和关闭文件,但是如果程序有Bug,导致close()语句未执行,文件将不会关闭,可能会导致数据丢失或受损。如果过早调用close(),会发现需要使用文件时它已经关闭,会导致更多错误。
方法read()读取这个文件的全部内容,并将其作为一个长长的字符串存储在变量contents中;到达文件末尾时返回一个空字符串,显示出来为一个空行,可用restrip()方法删除
文件路径
将'pi_digits.txt'传给open()时,Python将在当前执行的文件所在目录中查找文件
使用相对文件路径打开文件:Python到相对于当前运行的程序所在目录进行查找
with open('text_files\filename.txt') as file_object:
使用绝对路径:可读取系统任何地方的文件
file_path = 'C:\Users\19405\Desktop\filename.txt'
with open(file_path ) as file_object:
绝对路径通常比相对路径更长,因此将其存储在一个变量中,再将该变量传递给open()会有所帮助
逐行读取
file_path = 'pi_digits.txt' with open(file_path) as file_object: for line in file_object: print(line)
消除多余空白行:
print(line.rstrip())
创建一个包含文件各行内容的列表
使用关键字with时,open()返回的文件对象只在with代码块内可用
filename = 'pi_digits.txt' with open(filename) as file_object: lines = file_object.readlines() for line in lines: print(line.rstrip())
方法readlines()从文件中读取每一行,并将其存储再一个列表中
filename = 'pi_digits.txt' with open(filename) as file_object: lines = file_object.readlines() pi_string = '' for line in lines: pi_string += line.strip() print(pi_string) print(len(pi_string))
包含一百万位的大型文件
filename = 'pi_million_digits.txt' --snip-- print(pi_string[:52] + '...') print(len(pi_string))
birthday = input("Enter your birthday, in the form mmddyy: ") if birthday in pi_string: print("Your birthday appears in the first million digits of pi") else: print("No")
保存数据最简单的方式之一
写入空文件
filename = 'programming.txt' with open(filename, 'w') as file_object: file_object.write("I love programming.")
open()的第二个实参:
'r':读取模式
'a':附加模式
'r+':读取和写入模式
Python只能将字符串写入文本文件
写入多行
函数write()不会再你写入的文本末尾添加换行符,因此写入多行时需要指定换行符
filename = 'programming.txt' with open(filename, 'w') as file_object: file_object.write("I love programming.\n") file_object.write("I love creating new games.\n")
给文件添加内容,而不是覆盖原有的内容
附加模式
filename = 'programming.txt' with open(filename, 'a') as file_object: file_object.write("I also love finding meaning in large datasets.\n") file_object.write("I love creating new games.\n")
异常
每当发生错误时,都会创建一个异常对象
异常是使用try-except代码块处理的。使用了该模块,即便出现异常,程序也将继续运行
处理ZeroDivisionError异常
print(5/0)
程序运行失败,并返回一个Traceback,创建了一个ZeroDivisionError对象
使用try-except代码块
编写一个try-except代码块来处理可能发生的异常
try: print(5 / 0) except ZeroDivisionError: print("You can't divide by zero")
如果try代码块中的代码运行没有问题,将跳过except代码块;
如果try代码块的代码导致了错误,Python将查找这样的expect代码块,并运行其中的代码,即其中指定的错误与引发的错误相同
经常用于要求用户提供输入的程序中
如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入,而不至于崩溃
division.py
print("Give me two number, and I will divide them.") print("Enter 'q' to quit.") while True: first_number = input("\nFirst number: ") if first_number == 'q': break second_number = input("\nSecond number: ") if second_number == 'q': break answer = int(first_number) / int(second_number) print(answer)
second_number输入为0会导致程序崩溃
将可能引发错误地代码放在try-except代码块中,可提高这个程序地低于错误地能力
print("Give me two number, and I will divide them.") print("Enter 'q' to quit.") while True: first_number = input("\nFirst number: ") if first_number == 'q': break second_number = input("\nSecond number: ") if second_number == 'q': break try: answer = int(first_number) / int(second_number) except ZeroDivisionError: print("You can't divide by 0!") else: print(answer)
依赖于try代码块成功执行地代码都放在else代码块中
处理FileNotFoundError异常
找不到文件
filename = 'alice.txt' try: with open(filename) as f_obj: contents = f_obj.read() except FileNotFoundError: print("Sorry, the file " + filename + " dose not exist.")
分析文本
split()方法:根据一个字符串创建一个单词列表;以空格为分隔符拆分字符串
def count_words(filename): """计算一个文件大致包含多少单词""" try: with open(filename) as f_obj: contents = f_obj.read() except FileNotFoundError: print("Sorry, the file " + filename + " dose not exist.") else: # 计算文件大致包含多少个单词 words = contents.split() num_words = len(words) print("The file " + filename + " has about " + str(num_words) + "words.") filename = 'alice.txt' count_words(filename)
在expect代码块中明确告诉Python什么都不要做
pass语句:让Python什么都不做
except FileNotFoundError: pass
决定报告哪些错误
凭借经验判断该在程序地什么地方包含异常处理块,以及出现错误时该向用户提供多少相关信息
存储数据
使用模块josn来存储数据
使用json.dump()和json.load()
json.dump()存储数据列表
import json numbers = [2, 3, 5, 7, 11, 13] filename = 'numbers.json' with open(filename, 'w') as f_obj: json.dump(numbers, f_obj)
json.load()将列表读取到内存中
import json filename = 'numbers.json' with open(filename) as f_obj: numbers = json.load(f_obj) print(numbers)
import json #如果以前存储了用户名,就加载它;否则,就提示用户输入用户名并存储它 filename = 'name.json' try: with open(filename) as f_obj: username = json.load(f_obj) except FileNotFoundError: username = input("What's your name: ") with open(filename, 'w') as f_obj: json.dump(username, f_obj) print("Hello, " + username) else: print("Welcome back, " + str(username) + "!")
重构
import json def get_stored_username(): """如果存储了用户名,就获取它""" filename = 'name.json' try: with open(filename) as f_obj: username = json.load(f_obj) except FileNotFoundError: return None else: return username def get_new_username(): """提示用户输入用户名""" username = input("What's your name: ") filename = 'name.json' with open(filename, 'w') as f_obj: json.dump(username, f_obj) return username def greet_user(): """问候用户,并指出其名字""" username = get_stored_username() if username: print("Welcome back, " + username + "!") else: username = get_new_username() print("We'll remeber you when you come back, " + username + "!") greet_user()

浙公网安备 33010602011771号