目录
10.1 从文件中读取数据
10.1.1 读取整个文件
10.1.2 文件路径
10.1.3 逐行读取
10.1.4 创建一个包含文件各行内容的列表
10.1.5 使用文件的内容
10.1.6 包含一百万位的大型文件
10.1.7 练习
练习10-1:Python学习笔记
练习10-2:C语言学习笔记
10.2 写入文件
10.2.1 写入空文件
10.2.2 写入多行
10.2.3 附加到文件
10.2.4 练习
练习10-3:访客
练习10-4:访客名单
练习10-5:调查
10.3 异常
10.3.1 处理ZeroDivisionError 异常
10.3.2 使用try-except 代码块
10.3.3 使用异常避免崩溃
10.3.4 else 代码块
10.3.5 处理FileNotFoundError 异常
10.3.6 分析文本
10.3.7 使用多个文件
10.3.8 静默失败
10.3.9 决定报告哪些错误
10.3.10 练习
练习10-6:加法运算
练习10-7:加法计算器
练习10-8:猫和狗
练习10-9:静默的猫和狗
练习10-10:常见单词
10.4 存储数据
10.4.1 使用json.dump() 和json.load()
10.4.2 保存和读取用户生成的数据
10.4.3 重构
10.4.4 练习
练习10-11:喜欢的数
练习10-12:记住喜欢的数
练习10-13:验证用户
文本文件可存储的数据量多得难以置信:天气数据、交通数据、社会经济数据、文学作品等。每当需要分析或修改存储在文件中的信息时,读取文件都很有用,对数据分析应用程序来说尤其如此。例如,可以编写一个这样的程序:读取一个文本文件的内容,重新设置这些数据的格式并将其写入文件,让浏览器能够显示这些内容。
3.1415926535
8979323846
2643383279
with open('D:\\python_work\\chapter10\\pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)
3.1415926535
8979323846
2643383279
将类似于pi_digits.txt的简单文件名传递给函数open() 时,Python将在当前执行的文件(即.py程序文件)所在的目录中查找。
with open('text_files/filename.txt') as file_object:
注意 示文件路径时,Windows系统使用反斜杠(\ )而不是斜杠( / ),但在代码中依然可以使用斜杠。
还可以将文件在计算机中的准确位置告诉Python,这样就不用关心当前运行的程序存储在什么地方了。这称为绝对文件路径 。在相对路径行不通时,可使用绝对路径。例如,如果text_files并不在文件夹python_work中,而在文件夹other_files中,则向open() 传递路径'text_files/filename .txt' 行不通,因为Python只在文件夹python_work中查找该位置。为明确指出希望Python到哪里去查找,需要提供完整的路径。
file_path = '/home/ehmatthes/other_files/text_files/_filename_.txt'
with open(file_path) as file_object:
通过使用绝对路径,可读取系统中任何地方的文件。就目前而言,最简单的做法是,要么将数据文件存储在程序文件所在的目录,要么将其存储在程序文件所在目录下的一个文件夹(如text_files)中。
注意 如果在文件路径中直接使用反斜杠,将引发错误,因为反斜杠用于对字符串中的字符进行转义。例如,对于路径 "C:\path\to\file.txt" ,其中的 \t 将被解读为制表符。如果一定要使用反斜杠,可对路径中的每个反斜杠都进行转义,如 "C:\\path\\to\\file.txt" 。
filename = 'D:\\python_work\\chapter10\\pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line)
3.1415926535
8979323846
2643383279
filename = 'D:\\python_work\\chapter10\\pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
3.1415926535
8979323846
2643383279
filename = 'D:\\python_work\\chapter10\\pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
filename = 'D:\\python_work\\chapter10\\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))
3.1415926535 8979323846 2643383279
36
--snip--
for line in lines:
pi_string += line.strip()
print(pi_string)
print(len(pi_string))
3.141592653589793238462643383279
32
注意 读取文本文件时,Python将其中的所有文本都解读为字符串。如果读取的是数,并要将其作为数值使用,就必须使用函数 int() 将其转换为整数或使用函数 float() 将其转换为浮点数。
filename = 'pi_million_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
print(f"{pi_string[:52]}...")
print(len(pi_string))
3.14159265358979323846264338327950288419716939937510...
1000002
file_name = 'D:\\python_work\\chapter10\\practice10_1.txt'
with open(file_name) as file_object:
print(file_object)
lines = file_object.readlines()
print(lines)
for line in lines:
print(line.rstrip())
file_name = 'D:\\python_work\\chapter10\\practice10_1.txt'
with open(file_name) as file_object:
print(file_object)
lines = file_object.readlines()
print(lines)
for line in lines:
line = line.rstrip()
print(line.replace('python', 'C'))
filename = 'programming.txt'
# ❶
with open(filename, 'w') as file_object:
# ❷
file_object.write("I love programming.")
在本例中,调用open() 时提供了两个实参(见❶)。第一个实参也是要打开的文件的名称。第二个实参('w' )告诉Python,要以写入模式 打开这个文件。打开文件时,可指定读取模式 ('r' )、写入模式 ('w' )、附加模式 ('a' )或读写模式 ('r+' )。如果省略了模式实参,Python将以默认的只读模式打开文件。
I love programming.
注意 Python只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数 str() 将其转换为字符串格式。
filename = 'programming.txt'
with open(filename, 'w') as file_object:
file_object.write("I love programming.")
file_object.write("I love creating new games.")
I love programming.I love creating new games.
filename = 'programming.txt'
with open(filename, 'w') as file_object:
file_object.write("I love programming.\n")
file_object.write("I love creating new games.\n")
I love programming.
I love creating new games.
filename = 'programming.txt'
with open(filename, 'a') as file_object:
file_object.write("I also love finding meaning in large datasets.\n")
file_object.write("I love creating apps that can run in a browser.\n")
I love programming.
I love creating new games.
I also love finding meaning in large datasets.
I love creating apps that can run in a browser.
file_name = 'D:\\python_work\\chapter10\\guest.txt'
with open(file_name, 'a') as gu:
print("you can quit any time if you input q")
while True:
x = input("please input your name:\n")
if x == 'q':
break
else:
gu.write(f"{x}\n")
file_name = 'D:\\python_work\\chapter10\\guest.txt'
with open(file_name, 'a') as gu:
print("you can quit any time if you input q")
while True:
x = input("please input your name:\n")
if x == 'q':
break
else:
gu.write(f"{x}\n")
file_name_1 = "D:\\python_work\\chapter10\\guest_book.txt"
with open(file_name_1, 'a') as gu:
print("you can quit any time if you input q")
while True:
x = input("please input your name:\n")
if x == 'q':
break
else:
gu.write(f"{x}\n")
print(f"Good day!{x}")
file_name_2 = "D:\\python_work\\chapter10\\reasons.txt"
with open(file_name_2, 'a') as fu:
print("you can quit any time if you input q")
while True:
x = input("why do you like progamme\n")
if x == 'q':
break
else:
fu.write(f"{x}\n")
print(f"Good day!{x}")
print(5/0)
Traceback (most recent call last):
File "division_calculator.py", line 1, in
print(5/0)
❶ ZeroDivisionError: division by zero
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
You can't divide by zero!
print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
# ❶
first_number = input("\nFirst number: ")
if first_number == 'q':
break
# ❷
second_number = input("Second number: ")
if second_number == 'q':
break
# ❸
answer = int(first_number) / int(second_number)
print(answer)
Give me two numbers, and I'll divide them.
Enter 'q' to quit.
First number: 5
Second number: 0
Traceback (most recent call last):
File "division_calculator.py", line 9, in
answer = int(first_number) / int(second_number)
ZeroDivisionError: division by zero
print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
first_number = input("\nFirst number: ")
if first_number == 'q':
break
second_number = input("Second number: ")
if second_number == 'q':
break
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by 0!")
else:
print(answer)
Give me two numbers, and I'll divide them.
Enter 'q' to quit.
First number: 5
Second number: 0
You can't divide by 0!
First number: 5
Second number: 2
2.5
First number: q
filename = 'alice.txt'
with open(filename, encoding='utf-8') as f:
contents = f.read()
Traceback (most recent call last):
File "alice.py", line 3, in
with open(filename, encoding='utf-8') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'
filename = 'alice.txt'
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
print(f"Sorry, the file {filename} does not exist.")
Sorry, the file alice.txt does not exist.
>>> title = "Alice in Wonderland"
>>> title.split()
['Alice', 'in', 'Wonderland']
filename = 'alice.txt'
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
print(f"Sorry, the file {filename} does not exist.")
else:
# 计算该文件大致包含多少个单词。
❶ words = contents.split()
❷ num_words = len(words)
❸ print(f"The file {filename} has about {num_words} words.")
The file alice.txt has about 29465 words.
def count_words(filename):
"""计算一个文件大致包含多少个单词。"""
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
print(f"Sorry, the file {filename} does not exist.")
else:
words = contents.split()
num_words = len(words)
print(f"The file {filename} has about {num_words} words.")
filename = 'alice.txt'
count_words(filename)
def count_words(filename):
--snip--
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
count_words(filename)
The file alice.txt has about 29465 words.
Sorry, the file siddhartha.txt does not exist.
The file moby_dick.txt has about 215830 words.
The file little_women.txt has about 189079 words.
def count_words(filename):
"""计算一个文件大致包含多少个单词。"""
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
pass
else:
words = contents.split()
num_words = len(words)
print(f"The file {filename} has about {num_words} words.")
filename = 'alice.txt'
count_words(filename)
--snip--
The file alice.txt has about 29465 words.
The file moby_dick.txt has about 215830 words.
The file little_women.txt has about 189079 words.
print("please input two numbers:")
while True:
a = input("please input the first number:\n")
try:
a = int(a)
except ValueError:
print("please input numbers!not text!")
else:
break
while True:
b = input("please input the second number:\n")
try:
b = int(b)
except ValueError:
print("please input numbers!not text!")
else:
break
print(a + b)
print("please input two numbers:")
while True:
a = input("please input the first number:\n")
try:
a = int(a)
except ValueError:
print("please input numbers!not text!")
else:
break
while True:
b = input("please input the second number:\n")
try:
b = int(b)
except ValueError:
print("please input numbers!not text!")
else:
break
print(a + b)
file_name_1 = 'D:\\python_work\\chapter10\\cats.txt'
file_name_2 = 'D:\\python_work\\chapter10\\dogs.txt'
try:
with open(file_name_1, 'r') as ca:
cats_lines = ca.readlines()
for cat_line in cats_lines:
print(cat_line.rstrip())
except FileNotFoundError:
print(f"Sorry, the file {file_name_1} does not exist.")
try:
with open(file_name_2, 'r') as do:
dogs_lines = do.readlines()
for dog_line in dogs_lines:
print(dog_line.rstrip())
except FileNotFoundError:
print(f"Sorry, the file {file_name_2} does not exist.")
file_name_1 = 'D:\\python_work\\chapter10\\cats.txt'
file_name_2 = 'D:\\python_work\\chapter10\\dogs.txt'
try:
with open(file_name_1, 'r') as ca:
cats_lines = ca.readlines()
for cat_line in cats_lines:
print(cat_line.rstrip())
except FileNotFoundError:
pass
try:
with open(file_name_2, 'r') as do:
dogs_lines = do.readlines()
for dog_line in dogs_lines:
print(dog_line.rstrip())
except FileNotFoundError:
pass
>>> line = "Row, row, row your boat"
>>> line.count('row')
2
>>> line.lower().count('row')
3
注意 JSON(JavaScript Object Notation)格式最初是为JavaScript开发的,但随后成了一种常见格式,被包括Python在内的众多语言采用。
import json
numbers = [2, 3, 5, 7, 11, 13]
#❶
filename = 'numbers.json'
#❷
with open(filename, 'w') as f:
#❸
json.dump(numbers, f)
[2, 3, 5, 7, 11, 13]
下面再编写一个程序,使用json.load() 将列表读取到内存中:
import json
#❶
filename = 'numbers.json'
#❷
with open(filename) as f:
#❸
numbers = json.load(f)
print(numbers)
[2, 3, 5, 7, 11, 13]
import json
❶
username = input("What is your name? ")
filename = 'username.json'
with open(filename, 'w') as f:
❷ json.dump(username, f)
❸ print(f"We'll remember you when you come back, {username}!")
What is your name? Eric
We'll remember you when you come back, Eric!
import json
filename = 'username.json'
with open(filename) as f:
❶ username = json.load(f)
❷ print(f"Welcome back, {username}!")
Welcome back, Eric!
import json
# 如果以前存储了用户名,就加载它。
# 否则,提示用户输入用户名并存储它。
filename = 'username.json'
try:
❶ with open(filename) as f:
❷ username = json.load(f)
❸ except FileNotFoundError:
❹ username = input("What is your name? ")
❺ with open(filename, 'w') as f:
json.dump(username, f)
print(f"We'll remember you when you come back, {username}!")
else:
print(f"Welcome back, {username}!")
What is your name? Eric
We'll remember you when you come back, Eric!
Welcome back, Eric!
import json
def greet_user():
#❶
"""问候用户,并指出其名字。"""
filename = 'username.json'
try:
with open(filename) as f:
username = json.load(f)
except FileNotFoundError:
username = input("What is your name? ")
with open(filename, 'w') as f:
json.dump(username, f)
print(f"We'll remember you when you come back, {username}!")
else:
print(f"Welcome back, {username}!")
greet_user()
import json
def get_stored_username():
# ❶
"""如果存储了用户名,就获取它。"""
filename = 'username.json'
try:
with open(filename) as f:
username = json.load(f)
except FileNotFoundError:
# ❷
return None
else:
return username
def greet_user():
"""问候用户,并指出其名字。"""
username = get_stored_username()
# ❸
if username:
print(f"Welcome back, {username}!")
else:
username = input("What is your name? ")
filename = 'username.json'
with open(filename, 'w') as f:
json.dump(username, f)
print(f"We'll remember you when you come back, {username}!")
greet_user()
import json
def get_stored_username():
"""如果存储了用户名,就获取它。"""
--snip--
def get_new_username():
"""提示用户输入用户名。"""
username = input("What is your name? ")
filename = 'username.json'
with open(filename, 'w') as f:
json.dump(username, f)
return username
def greet_user():
"""问候用户,并指出其名字。"""
username = get_stored_username()
if username:
print(f"Welcome back, {username}!")
else:
username = get_new_username()
print(f"We'll remember you when you come back, {username}!")
greet_user()
import json
file_name = 'favorite_numbers.json'
def get_stored_numbers():
"""如果存储了数字,就想用户展示他"""
try:
with open(file_name, 'r') as fn:
favorite_num = json.load(fn)
except FileNotFoundError:
return None
else:
return favorite_num
def greet_user():
"""greet user"""
favorite_num = get_stored_numbers()
if favorite_num:
print(f"I know your favorite number! It's {favorite_num}")
else:
favorite_num = input("what your favorite numbers:\n")
with open(file_name, 'w') as f:
json.dump(favorite_num, f)
print(f"We'll remember you when you come back, {favorite_num}!")
greet_user()
# 见练习10-11
--snip--
def certify_user():
"""验证用户名是否正确"""
print(f"Are you {get_stored_username()}?")
x = input("input 'yes' or 'no'\n")
if x == 'yes':
greet_user()
else:
get_new_username()
certify_user()