读取文本文件
现有文件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.")