Python-基础入门-学习笔记(6):文件和异常

本文详细介绍了Python中文件操作的基本方法,包括读取、写入、逐行读取及异常处理技巧,帮助初学者掌握如何在Python中高效处理文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)
  1. 开始时我们文件夹中没有favorite_number.json,所以执行except。
    在这里插入图片描述
  2. 我们输入数字3后,该字符存储到JSON文件中,如图所示,系统自动创建了JSON文件并在其中存储字符3。
    在这里插入图片描述
  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()

能看到这里的一定是有缘之人,感谢您对我的支持,走之前可否留个赞鼓励一下键盘后的我不断进步^ - ^
万分感谢~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值