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.")
相关推荐
2301_822382762 小时前
开发一个简单的Python计算器
jvm·数据库·python
ValhallaCoder2 小时前
hot100-子串
数据结构·python·算法
lambert.wang2 小时前
当使用 uv 下载 Python 解释器时出现异常,通常是因为网络连接问题导致无法从 GitHub 下载安装包
python·github·uv
2501_920999272 小时前
Django全栈开发入门:构建一个博客系统
jvm·数据库·python
码农阿豪2 小时前
影刀RPA与Java融合实践:打造高效智能的高铁票务解决方案
java·python·rpa
喵手2 小时前
Python爬虫实战:采集行业协会、研究机构等平台的政策文件列表与PDF链接批量收集系统,支持自动下载、分类归档和数据库管理(SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·sqlite持久化存储·采集行业协会、研究机构政策文件·pdf链接采集
diediedei2 小时前
用Pygame开发你的第一个小游戏
jvm·数据库·python
还是奇怪2 小时前
Python第四课:循环与数据结构深度解析
数据结构·windows·python·青少年编程·循环
2301_790300962 小时前
用Python制作一个文字冒险游戏
jvm·数据库·python