Python-基础入门-学习笔记(6):文件和异常
一、从文件中读取数据
要使用文本文件中的信息,首先需要将信息读取到内存中。
1、读取整个文件
假设我们要打开一个文件:pi_digits.txt。我们需要将其存储在本章程序所在的目录中。
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)
运行过程:open()函数接受一个参数,要打开的文件名称。然后Python在当前执行的文件所在的目录中查找指定的文件。随后函数open()返回一个表示文件的对象。
关键字with在不再需要访问文件后将其关闭。你也可以通过close()函数对文件进行关闭,但是可能会存在BUG。
read()到达文件末尾时会返回一个空字符串,你可以通过调用rstrip()对其进行删除。
2、文件路径
有时可能打开不在程序文件所属目录的文件,我们需要对其路径进行指定。
with open('text_files\filename.txt') as file_object:
在Linux和OS X中,用斜杠(/),而在windows系统中,用反斜杠(\)。
你还可以将文件在计算机中的准确位置告诉Python,这样就不用关心当前运行的程序存储在什么地方了,这称为绝对文件路径。
file_path = 'E:\postgraduate\study\Python\unit_10\text_files\filename.txt'
with open(file_path) as file_object:
3、逐行读取
你可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。
filename = ''pi_digits.txt''
with open(filename) as file_object:
for line in file_object: #逐行读取
print(line) #打印每一行
4、创建一个包含各行内容的列表
使用关键字with时,open()返回的对象只能在with代码块内可用。如果要在with代码块外访问文件内容,可在with代码块内将文件的各行存储在一个列表中,并在with代码块外使用该列表。
filename = ''pi_digits.txt''
with open(filename) as file_object:
for line in file_object: #逐行读取
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
5、使用文件中的内容
filename = ''pi_digits.txt''
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ' '
for line in lines:
pi_string += line.rstrip()
print(pi_string)
print(len(pi_string))
读取文本文件时,Python将其中的所有文本都解读为字符串。如果你读取的是数字,并要将其作为数值使用,就必须使用函数进行类型转换,例如int()。
练习
filename = 'learning_python.txt'
#直接读取的方法
with open(filename) as file_object:
contents = file_object.read()
print(contents)
print("\n")
#逐行读取
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
print("\n")
#存储在列表中再读取
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
print("\n")
#替换其中的元素并打印
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
#由于replace语句针对于字符,所以放在这里
line = line.replace('Python','C')
print(line.rstrip())
二、写入文件
1、写入空文件
filename = 'programming.txt'
with open(filename,'w') as file_object:
file_object.write("I love programming.")
在open()函数中,第一个实参是要打开的文件的名称;第二个实参是以什么模式打开这个文件。打开文件时,可指定读取模式(‘r’)、写入模式(‘w’)、附加模式(‘a’) 或者能够 读取和写入文件的模式(‘r+’)。
如果忽略了模式实参,Python将以默认的只读模式打开文件。
以(‘w’)模式打开时,如果指定的文件已经存在,将在返回文件对象前清空该文件。
Python只能将字符串写入文本文件,如果是数值数据,需要进行str()转换。
2、写入多行
filename = 'programming.txt'
with open(filename,'w') as file_object:
file_object.write("I love programming.")
file_object.write("I love creating new games.")
默认Python写入不换行,如果你想打印换行效果,请在末尾加\n。
3、附加到文件
如果想要给文件添加内容,而不覆盖原有内容,可以打开附加模式(给第二个实参设为(‘a’))。
练习
#存入访客
filename = 'guest.txt'
with open(filename,'w') as file_object:
prompt = "Please enter the guest's name."
prompt += "\n(Enter 'quit' when you are finished.)"
while True:
guests = input(prompt)
if guests == 'quit':
break
else:
file_object.write("Welcome " + guests.title())
三、异常
每当Python发生错误时,都会创建一个异常对象。如果编写了处理该异常的代码,程序将继续运行;如果未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。
1、处理ZeroDivisionError异常
print(5/0)
结果告诉我们,0不能被整除,这里会显示出错误原因。
2、使用try-except代码块
通过使用错误,可以控制当发生错误时应该执行什么。
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
代码表示运行try的语句,如果没问题跳过except,如果有问题将查找except代码块,并运行其中的代码。
如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入,不至于崩溃。
3、else代码块
依赖于try代码块都应放到else代码块中。
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
else:
print(answer)
except告诉python,如果它尝试运行try代码块中的代码时引发了指定的异常,该怎么办。
4、处理FileNotFoundError异常
使用文件时,一种常见的问题是找不到文件。
filename = 'alice.txt'
with open(filename) as f_obj:
contents = f_obj.read()
我们知道这个错误是open导致的,因此要处理这个错误,必须将try语句放在包含open()的代码行之前。
filename = 'alice.txt'
try:
with open(filename) as f_obj:
contents = f_obj.read()
except FileNotFoundError:
msg = "Sorry, the file " + filename + "does not exist."
print(msg)
总结一下:try后面放的是可能发生错误执行的任务,except后面写错误代号加冒号后发生错误时该执行什么,else后面写如果没有错误该怎么执行。
如果添加了处理错误功能,那么在发生错误时会有某种执行办法,并且会继续执行接下来得任务。但如果没有天剑该功能,那么在发生错误时系统会停止运行,并显示traceback。
5、分析文本
title.split() #根据字符串来创建一个单词列表
以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。
6、错误跳过
try:
print(5/0)
except ZeroDivisionError:
pass #该语句为直接跳过这个环节
else:
print(answer)
pass语句还充当了占位符,它提醒你在程序的某个地方什么都没做,并且以后也许要在这里做些什么。
练习
#设置异常时执行方式
print("Give me two numbers,and I will add 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 ValueError:
print("Please enter the number!")
else:
print(answer)
#分析文本结合异常处理
def show_words(filename):
"""打印文本中的单词"""
try:
with open(filename) as f_obj:
contents = f_obj.read()
except FileNotFoundError:
msg = "Sorry, the file " + filename + " does not exist."
print(msg)
else:
words = contents.split()
print(words)
filename = 'cat.txt'
show_words(filename)
filename = 'dog.txt'
show_words(filename)
#计算文本中单词'the'的个数
filename = 'passage.txt'
try:
with open(filename) as f_obj:
contents = f_obj.read()
except FileNotFoundError:
msg = "Sorry, the file " + filename + " does not exist."
print(msg)
else:
number = contents.lower().count('the')
#读取的为int型,打印时需要转为str型
number = str(number)
print("The number of 'the' is " + number)
四、存储数据
用户关闭程序时,几乎总是要保存他们提供的信息:一种简单的方式是使用模块json来存储数据,可以将简单的python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。
JSON格式存储的数据可以与使用其他编程语言的人分享。
1、使用json函数
函数json.dump()接受两个实参:要存储的数据以及可用于存储数据的文件对象。
import json
numbers = [2,3,5,7,11,13]
filename = 'numbers.json' #指定了数字要存储的文件名称(格式为JSON)
with open(filename,'w') as f_obj: #以写入模式打开这个文件
json.dump(numbers,f_obj) #将数字列表存储到文件中
函数json.load()是用来加载文件中的信息的。
import json
filename = 'number.json'
with open(filename) as f_obj: #以读取模式打开这个文件
numbers = json.load(f_obj) #将该文件中的内容加载出来并赋给numbers
print(numbers)
2、保存和读取用户生成的数据
对于用户生成的数据,使用json保存它们大有好处,因为如果不以某种方式进行存储,程序停止运行时用户的信息将会丢失。
我们可以在一开始用json.dump()函数将信息存储到JSON文件中,这样在下次打开时用json.load()函数加载储之前存好的信息,从而实现了数据的保存和读取功能。
3、重构
代码能够正确地运行,但可做进一步的改进,将代码划分为一系列完成具体工作的函数,成为重构。
接下来我们对用户访问程序进行重构处理:
import json
def get_stored_username():
"""如果存储了用户名,就获取它"""
filename = 'username.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 is your name? ")
filename = 'username.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 will remeber you when you come back, " + username + "!")
greet_user()
这样每个函数都有其特定的功能,用到哪个函数就调用哪个函数,清晰明了。要编写出清晰而易于维护和扩展的代码,这种划分必不可少。
练习
#将一个数存储在JSON文件中
import json
number = input("Please enter your favorite number.")
filename = 'favorite_number.json'
with open(filename,'w') as f_obj:
json.dump(number,f_obj)
#读取上一步存储在JSON文件中的内容
import json
filename = 'favorite_number.json'
with open(filename) as f_obj:
number = json.load(f_obj)
print("I know your favorite number!It's " + number)
接下来是整合起来的程序:
#将存储和读取整合为一个
import json
#如果以前存储了数字,就显示它
#否则,就提示用户输入数字并存储它
filename = 'favorite_number.json'
try:
with open(filename) as f_obj:
number = json.load(f_obj)
except FileNotFoundError:
number = input("Please enter your favorite number.")
with open(filename,'w') as f_obj:
number = json.dump(number,f_obj)
else:
print("I know your favorite number!It's " + number)
- 开始时我们文件夹中没有favorite_number.json,所以执行except。
- 我们输入数字3后,该字符存储到JSON文件中,如图所示,系统自动创建了JSON文件并在其中存储字符3。
- 之后我们再次运行程序,由于JSON文件产生,所以执行else,显示数字。
#重构
import json
def get_stored_username():
"""如果存储了用户名,就获取它"""
filename = 'username.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 is your name? ")
filename = 'username.json'
with open(filename,'w') as f_obj:
json.dump(username,f_obj)
return username
def identify_username(username):
"""确认用户信息是否是本人"""
while True:
print("Are you the " + username + ".\n")
result = input("Please enter yes or no.\n")
if result == 'yes':
print("Welcome back, " + username + "!")
break
elif result == 'no':
username = get_new_username()
print("We'll remember you when you come back, " + username + "!")
break
else:
print("Please enter yes or no!")
def greet_user():
"""问候用户,并指出其名字"""
username = get_stored_username()
if username:
identify_username(username)
else:
username = get_new_username()
print("We'll remember you when you come back, " + username + "!")
greet_user()
能看到这里的一定是有缘之人,感谢您对我的支持,走之前可否留个赞鼓励一下键盘后的我不断进步^ - ^
万分感谢~