Python -- 文件和异常

读取文本文件

现有文件read_it.txt

Line 1

This is the line 2

That makes this line 3

打开文件open()

读取文件前,需要先打开打开文件,open(文件名,访问模式)函数,用来打开一个文件

text_file = open("read_it.txt", "r")

打开文件 "read_it.txt",并将结果赋值给text_file

关闭文件close()

完成对文件的操作后,要将其关闭,这是一个好习惯。close()函数,可以用来关闭一个文件

text_file.close()

文本文件访问模式

| 模式 | 说明 |
| "r" | 读取文本文件。如果文件不存在,Python将会给出一个错误 |
| "w" | 写入文本文件。如果文件已存在,则会被覆盖。如果文件不存在,会被创建出来。 |
| "a" | 向文本文件添加内容。如果文件已存在,则新数据会被添加进去。如果文件不存在,则会被创建出来 |
| "r+" | 读写文本文件。如果文件不存在,Python将会给出一个错误。 |
| "w+" | 写入文本文件。 如果文件已存在,则会被覆盖。如果文件不存在,则会被创建出来 |

"a+" 读取文本文件以及向文件添加内容。如果文件已存在,则新数据会被添加进去。如果文件不存在,则会被创建出来

按字符读取文件read(number)

文件对象方法read()用来读取文件内容,入参传入一个数值,可以从文件中读取指定数量的字符,得到的结果以字符串形式返回。

text_file.read(1) # 读取一个字符,对应上面的read_it.txt文件中的字符就是"L"

text_file.read(5) # 读取五个字符,"ine 1",读取的是"L"之后的五个字符。

Python会记住刚才所打的位置,每次read()都会从上次结束的地方开始。当读到文件末尾处时,后面的读操作就只会返回空字符串。

读取整个文本文件read()

如果不指定字符数,Python会将整个文件以字符串的形式返回

text_file.read()

按行读取文件readline()

当需要一行一行地处理文件时,可以使用readline()方法,该方法用于读取当前行中的字符。入参传入一个字符数,就会从当前行中读出指定数量的字符,并以字符串形式返回。如果不指定字符数,则会从当前位置读取到行末。当前行中多有字符都被读取之后,下一行会成为当前行。

text_file.readline(1) # "L"

text_file.readline(5) # "ine 1"

与read()的区别在于,read()读取整个文件中的字符, readline()只会读取当前行中的字符。readline()通常用于一次读取一行文本

text_file.readline() # Line 1

text_file.readline() # This is line 2

text_file.readline() # That makes this line 3

将所有行读取为一个列表readlines()

readlines(),与readline()一样用于按行处理文本文件。 readlines()会将整个文本文件读取为一个列表,文件中的每行文本将会成为列表中的一个字符串元素。

lines = text_file.readlines() # 'Line 1\\n', 'This is the line 2\\n', 'That makes this line 3'

len(lines) # 3

for line in lines:

print(line) # 一行行打印出来

read_it.py

python 复制代码
# Read it
# 演示读取文本文件

print("Opening and closing the file.")

# 打开文件,(文件名,访问模式)
text_file = open("read_it.txt", "r")
# 关闭文件
text_file.close()

# 按字符读取文件
print("\nReading characters from the file.")
# 打开文件
text_file = open("read_it.txt", "r")
# 读取一个字符,并打印
print(text_file.read(1))
# 读取五个字符,并打印,从第二个字符开始读取,因为上面读了一个
print(text_file.read(5))
# 关闭文件
text_file.close()

# 一次读取整个文本文件
print("\nReading the entire file at once.")
text_file = open("read_it.txt", "r")
whole_thing = text_file.read()
print(whole_thing)
text_file.close

# 读取当前行中指定数量的字符
print("\nReading characters from a line.")
text_file = open("read_it.txt", "r")
print(text_file.readline(1))
print(text_file.readline(5))
text_file.close()

# 一次读取一行
print("\nReading one line at a time.")
text_file = open("read_it.txt", "r")
print(text_file.readline())
print(text_file.readline())
print(text_file.readline())
text_file.close()

print("\nReading the entire file into a list.")
text_file = open("read_it.txt", "r")
lines = text_file.readlines()
print(lines)
print(len(lines))
for line in lines:
	print(line)
text_file.close()

# 循环遍历文件
print("\nLooping through the file, line by line.")
text_file = open("read_it.txt", "r")
for line in text_file:
	print(line)
text_file.close()

input("\n\nPress the enter key to exit.")

写入文件

打开或新建文件open(文件名,访问模式)

先用open()函数打开一个文件,如果文件存在会被替换成一个新的空文件,如果文件不存在,会被创建。文件的访问模式为"w"

text_file = open("write_it.txt", "w")

write_it.txt文件会以空文本形式出现,等待程序向其写入内容。

如果writ_it.txt文件已存在,会被一个全新的空文件替换掉,所有原始内容都会被删除

向文件写入内容 write(output)

write()函数向文件内写入内容,write()函数不会自动在行末尾插入换行符,所以如果需要换行符的话,需要自行添加

text_file.write("Line 1\n")

text_file.write("This is line 2\n")

text_file.write("That makes this line 3\n")

写入完成后要关闭文件

text_file.close()

将字符串列表写入到文件writelines(output)

writelines()与readlines()一样用于字符串列表,readlines()是将文件内容读取到一个列表中,writelines()是将一个字符串列表写入到文件中

这里与上面打开的是同一个文件write_it.txt,所以现有文件会被替换为一个新的空文件

text_file = open("write_it.txt", "w")

这里第二个元素中没有添加换行符,所以会和第三个元素处于一行

lines = "New line 1\\n", "This is new line 2 ", "That makes this new line 3\\n"

将lines写入到文件中

text_file.writelines(lines)

text_file.close()

完整代码

write_it.py

python 复制代码
# Write it
# 演示文本文件的写入操作

print("Creating a text file with the write() method.")
# write_it.txt文件会以空文本形式出现,等待程序向其写入内容。
# 如果writ_it.txt文件已存在,会被一个全新的空文件替换掉,所有原始内容都会被删除
text_file = open("write_it.txt", "w")
# write()函数向文件内写入内容,write()函数不会自动在行末尾插入换行符,所以如果需要换行符的话,需要自行添加
text_file.write("Line 1\n")
text_file.write("This is line 2\n")
text_file.write("That makes this line 3\n")
text_file.close()

# 读取文件中的内容
print("\nReading the newly created file.")
text_file = open("write_it.txt", "r")
print(text_file.read())
text_file.close()

# 将字符串列表写入到文件
print("\nCreating a text file with writelines() method.")
# 这里与上面打开的是同一个文件write_it.txt,所以现有文件会被替换为一个新的空文件
text_file = open("write_it.txt", "w")
lines = ["New line 1\n", "This is new line 2", "That makes this new line 3\n"]
# 将lines写入到文件中
text_file.writelines(lines)
text_file.close()

# 读取文件中的内容
print("\nReading the newly created file.")
text_file = open("write_it.txt", "r")
print(text_file.read())
text_file.close()

存储复杂数据

如何将列表、字典之类更为复杂的信息存储到文本文件中呢?除了将其转换为字符串再保存到文本文件中,Python提供了一个方法,只需一行代码就可以将复杂数据保存到文件中去,还可以在单个文件中存储一个小型的数据库(功能就像字典)

下面用到的pickle和unpickle适用于存取结构化信息。更为复杂的信息则需要更高的性能和灵活性。数据库和XML是两种流行的复杂数据存取手段。

需要引入pickle 和 shelve模块

import pickle, shelve

pickle 和 shelve模块

pickle模块可以对复杂数据进行序列化处理并保存到文件中。

shelve模块也可以进行序列化处理并将结果保存到文件中,而且还可以对这些结果进行随机访问。

经过pickle处理的对象只能被写入到二进制文件,不能被写入到文本文件中。

f = open("pickles1.dat", "wb")

所以访问模式与上面访问文本文件的模式有所不同

模式 说明
"rb" 读取二进制文件。如果文件不存在,Python会给出一个错误
"wb" 写入二进制文件。如果文件已存在,内容会被覆盖。如果文件不存在,则会被创建出来
"ab" 向二进制文件添加内容。如果文件已存在,新数据被添加进去。如果文件不存在,会被创建出来
"rb+" 读写二进制文件。如果文件不存在,报错
"wb+" 读写二进制文件。如果文件已存在,覆盖其内容。如果文件不存在,则创建一个
"ab+" 读取二进制文件以及向二进制文件添加内容。如果文件已存在,新数据被添加进去。如果文件不存在,被创建出来

通过pickle处理对象

可以进行pickle处理的对象
  • 数字 number
  • 字符串 string
  • 元组 tuple
  • 列表 list
  • 字典 dictionary
将数据保存到二进制文件 pickle.dump()

pickle.dump(待pickle的数据, 用于存储的文件)

variety = "sweet", "hot", "dill"

pickle.dump(variety, f)

将variety所指向的列表序列化冰整体保存到pickles1.dat中

读取文件中的数据,并进行pickle处理 pickle.load()

pickle.load(file)函数用于获取反序列化的数据。file入参为序列化对象所在的文件

variety = pickle.load(f)

读取文件中的序列化对象,将其反序列化后产生的列表复制给variety

总结pickle的两个方法

函数 说明
dump(object, file, bin 将object序列化后写入file。如果bin 为True,则object将以二进制格式写入。如果bin为False,则object将以文本格式写入(虽然效率比较低,但可读性更好)。bin默认值为False
load(file) 从文件中读取下一个序列化对象,将其反序列化之后返回

通过shelf保存序列化对象

将多个列表shelve到单个文件中。

创建shelf,shelve.open()

shelve.open(文件, 访问模式),shelve的open()函数,所操作的文件中存放的是序列化对象而不是字符。访问模式是可选的,如果不指定,默认为"c"打开一个文件。

s = shelve.open("pickles2.dat")

调用shelve.open()是,Python可能会在指定的文件名后面添加一个扩展名。为了支持新创键的shelf对象,Python还可能会创建出额外的文件。

shelve访问模式
模式 说明
"c" 打开一个文件以便读写。如果文件不存在,就创建一个
"n" 创建一个写文件以便读写。如果文件已存在,则覆盖其内容
"r" 读取一个文件。如果文件不存在,报错
"w" 写入一个文件。如果文件已存在,报错
添加列表到shelf

s的用法类似于字典(dictionary),键"variety"和值 "sweet", "hot", "dill"是一对。

shelf对象的键只能是字符串。

s"variety" = "sweet", "hot", "dill"

Python现将对shelf文件的修改写入到一个缓冲区,然后再定期将缓冲区中的内容写入到文件。为了确保文件能反映出所有对shelf的修改,可以使用shelf的sync()方法。

s.sync() # 确保数据被写入

关闭文件的close()方法,也会实现sync()的功能。

shelf获取序列化对象

由于shelf的用法与字典类似,所以可以通过指定键的方式随机访问其中的系列化对象。

s"variety"

关闭文件

s.close()

完整代码:pickle_it.py

python 复制代码
# pickle it
# 演示数据的序列化处理(pickle和shelve)

import pickle, shelve

print("Pickling lists.")
# 定义列表
variety = ["sweet", "hot", "dill"]
shape = ["whole", "spear", "chip"]
brand = ["Claussen", "Heinz", "Vlassic"]

# 打开一个新文件,用以保存pickle之后的列表
f = open("pickles1.dat", "wb")

# 使用pickle.dump()对数据 进行pickle并将结果保存到二进制文件f中
pickle.dump(variety, f)
pickle.dump(shape, f)
pickle.dump(brand, f)

#关闭文件
f.close()

print("\nUnpickling lists.")
f = open("pickles1.dat", "rb")
# 读取文件中的第一个序列化列对象,将其反序列化后产生的数据赋值给变量variety
variety = pickle.load(f)
# 读取文件中的第二个序列化列对象,将其反序列化后产生的数据赋值给变量shape
shape = pickle.load(f)
# 读取文件中的第三个序列化列对象,将其反序列化后产生的数据赋值给变量brand
brand = pickle.load(f)

print(variety)
print(shape)
print(brand)
f.close()

print("\nShelving lists.")
# 打开一个shelf, 默认访问模式为"c"
s = shelve.open("pickles2.dat")

# shelf用法类似于字典,以键值对形式存储,且键只能为字符串。
# 将三个列表存储到s中
s["varitey"] = ["sweet", "hot", "dill"]
s["shape"] = ["whole", "spear", "chip"]
s["brand"] = ["Claussen", "Heinz", "Vlassic"]

# Python会将对shelf的所有修改暂存在缓冲区,然后定期将缓存区内的数据写入文件
#确保数据被写入
s.sync()

print("\nRetrieving lists from a shelved file: ")
# 通过键获取值,随机访问
print("brand -", s["brand"])
print("shape -", s["shape"])
print("variety -", s["variety"])
s.close()

input("\n\nPress the enter key to exit.")

异常 exception

当Python遇到错误时,会停止当前程序并显示出错误信息。这就是引发了一个异常(expection)

使用try/expect子句处理异常

基本句式:
try :

to do somthing...

except :

handle expections...

指定异常类型

指定一个异常类型:

try :

to do something...

except ValueError:

handled expection...

print(e)

else :

excute when no expection

说明:ValueError为一个异常类型,

对多种异常类型统一进行处理

try :

to do something...

except (TypeError, KeyError) :

handle expections...

对不同异常分开处理:

try :

to do something...

except TypeError :

handled TypeError expection

except KeyError :

handled KeyError expection

捕获异常的参数并添加 else 子句

try :

to do something...

except ValueError as e:

handled expection...

print(e)

else :

excute when no expection

说明:

ValueError为一个异常类型,

"as e" 是使用as关键字为异常类型指定一个变量,以便获取到异常的参数,进行处理

else:当try中的代码没有发生任何异常时,才会执行else中的代码

常见的异常类型
异常类型 说明
IOError 当I/O操作失败时引发。比如以读取模式打开一个不存在的文件
IndexError 以一个不存在的元素编号对序列进行索引操作时引发
KeyError 字典中找不到指定键时引发
NameError Raised 找不到指定名称时引发,比如变量或函数的名称
SyntaxError 出现语法错误时引发
TypeError 当内建运算或函数被应用于不正确的类型时引发
ValueError 当内建运算或函数所接受到的参数类型正确但值不合适时引发
ZeroDivisionError 当除法或求模运算的第二个参数为0时引发

Trivia Challenge游戏

先学一个单词 :

trivia /ˈtrɪviə/ noun plural

1、〔有关历史、体育运动、名人等的〕详细知识,细节

2、琐事,微不足道的细节

Trivia Challenge (知识挑战)游戏,通过一组多选题来测试玩家的知识面。将一批问题作为一个整体进行处理。整批问题都存储在一个独立文件中(独立于游戏代码之外),这样就可以轻松地对问题进行更换。

trivia.txt文件格式

<category>

<question>

<answer 1>

<answer 2>

<answer 3>

<answer 4>

<correct answer>

<explanation>

tivia.txt文件内容

An Episode You Can't Refuse.

On the Run With a Mammal.

Let's say you turn state's evidence and need to "get on the lamb." If you wait /too long, what will happen?

You'll end up on the sheep.

You'll end up on the cow.

You'll end up on the goat.

You'll end up on the emu.

1

A lamb is just a young sheep.

The Godfather Will Get Down With You Now.

Let's say you have an audience with the Godfather of Soul. How would it be /smart to address him?

Mr. Richard.

Mr. Domino.

Mr. Brown.

Mr. Checker.

3

James Brown is the Godfather of Soul.

trivial_challenge.py

python 复制代码
# Trivia Challenge
# 可以读取纯文本文件的益智游戏

import sys

# 定义打开文件的函数 
# file_name: 文件名
# mode: 访问模式
# return: 文件
def open_file(file_name, mode) :
	"""Open a file."""
	try:
		the_file = open(file_name, mode)
	except IOError as e :
		print("Unable to open the file", file_name, "Ending progra.\n", e)
		input("\n\nPress the enter key to exit.")
		# 终止程序。 sys模块的exit()函数会引发一个导致程序终止的异常
		sys.exit()
	else:
		return the_file

# 定义读取下一行函数
# the_file: 文件对象
# return: 下一行文本
def next_line(the_file) :
	"""Return next line from the trivia file, formatted."""
	# 接上次读取的位置,读取一行
	line = the_file.readline()
	# 格式化文本,将文本中的/替换为换行符
	line = line.replace("/", "\n")
	return line

# 定义读取下一个问题函数
# the_file: 文件对象
# return: 四个字符串以及一个字符串列表,四个字符串即 范围,问题,正确答案 ,说明。 
# 字符串列表中有四个字符串,分别表示该问题的一个可选项
def next_block(the_file) :
	"""Return the next block of data from the trivia file."""
	# 根据文本文件的格式,一行行读取
	category = next_line(the_file)

	question = next_line(the_file)

	# 答案有四个,定义答案列表
	answers = []
	# for 循环读取四个答案
	for i in range(4) :
		# 一行行读取,并添加到answer列表中
		answers.append(next_line(the_file))

	correct = next_line(the_file)
	if correct :
		# 获取字符串的第一个字符
		correct = correct[0]

	explanation = next_line(the_file)

	return category, question, answers, correct, explanation

# 定义欢迎函数,向玩家显示一些欢迎信息
# title: 题库标题
def welcome(title) :
	"""Welcome the player and get his/her name."""
	print("\t\tWelcome to Triviia Chaaallenge!\n")
	print("\t\t", title, "\n")

# 游戏初始化设置
def main() :
	trivia_file = open_file("trivia.txt", "r")
	title = next_line(trivia_file)
	welcome(title)
	# 玩家得分
	score = 0

	# 获取第一个问题,并赋值给相应的变量
	category, question, answers, correct, explanation = next_block(trivia_file)
	# while循环,一直提问题
	while category:
		# 提问
		print(category)
		print(question)
		for i in range(4):
			print("\t", i+1, "-", answers[i])
		# 获取答案
		answer = input("What's your answer?: ")
		# 判断答案
		if answer == correct :
			print("\nRight!", end = " ")
			score += 1
		else :
			print("\nWrong.", end = "\n")
		print(explanation)
		print("Score:", score, "\n\n")
		# 获取下一个问题,如果没有了category 返回空
		category, question, answers, correct, explanation = next_block(trivia_file)

	# 关闭文档
	trivia_file.close()
	print("That was the last question!")
	print("You're final score is", score)

# 调用main方法
main()
input("\n\nPress the enter key to exit.")
相关推荐
笨鸟先飞,勤能补拙4 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能5 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂5 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study6 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境6 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境7 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1237 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102167 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb008 小时前
一个项目带你入门AI应用开发01
python
0566468 小时前
Python康复训练——常用标准库
开发语言·python·学习