文件和异常
10.1.1读取整个文件
关键字with----在不再需要访问文件后关闭。
函数open() -----打开文件
close() -----关闭文件
方法read() ----读取文件
方法rstrip()—删除空白(字符串末尾)
with open('pi_digits.txt') as kingnsl:
contents = kingnsl.read()
print(contents.rstrip())
10.1.2文件路径
相对路径
with open('text/pi_digits.txt') as kingnsl:
绝对路径
with open('/hometext/pi_digits.txt') as kingnsl:
10.1.3逐行读取
使用for循环遍历
filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
10.1.4创建一个包含文件各行内容的列表
方法readlines()—从文件中读取每一行,并将其储存在一个列表中。
filename = 'pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
10.1.5使用文件的内容
方法strip()删除所有空格
filename = 'pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip() #这里是方法strip()
print(pi_string)
print(len(pi_string))
使用float()转换字符串为浮点数,只能显示小数点后15位?
10.1.6包含一百万位的大型文件
print(f"{pi_string[:50]}")
10.1.7圆周率值中包含你的生日吗
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()
birthday = input("请输入你的生日,如:201130:")
if birthday in pi_string:
print("你的生日出现在圆周率的第一个百万位数")
else:
print("你的生日不会出现在圆周率的第一个百万位数中")
练习10-1:python学习笔记
filename = 'learning_python.txt'
print("读取整个文件")
with open(filename) as file_object:
tachyon = file_object.read()
print(tachyon)
print("\n遍历文件对象")
with open(filename) as file_object:
for tachyon in file_object:
print(tachyon.rstrip())
print("\n文件储存在列表中")
with open(filename) as file_object:
tachyons = file_object.readlines()
for tachyon in tachyons:
print(tachyon.rstrip())
输出:
读取整个文件
In Python you can store as much information as you want.
In Python you can connect pieces of information.
In Python you can model real-world situations.
遍历文件对象
In Python you can store as much information as you want.
In Python you can connect pieces of information.
In Python you can model real-world situations.
文件储存在列表中
In Python you can store as much information as you want.
In Python you can connect pieces of information.
In Python you can model real-world situations.
[Finished in 0.1s]
练习10-2:C语言学习笔记
使用方法replace()替换字符串。
filename = 'learning_python.txt'
print("原文件")
with open(filename) as file_object:
tachyons = file_object.readlines()
for tachyon in tachyons:
print(tachyon.rstrip())
print("\n修改Python为C")
with open(filename) as file_object:
tachyons = file_object.readlines()
for tachyon in tachyons:
print(tachyon.replace('Python', 'C').rstrip())
输出:
原文件
In Python you can store as much information as you want.
In Python you can connect pieces of information.
In Python you can model real-world situations.
修改Python为C
In C you can store as much information as you want.
In C you can connect pieces of information.
In C you can model real-world situations.
[Finished in 0.1s]
替换严格大小写
如果读取的文件使用中文可将
with open(filename) as file_object:
改为:
with open(filename, encoding="utf8") as file_object:
10.2写入文件
10.2.1写入空文件
open()的第二个实参,‘w’ 写入模式,‘r’读取模式,‘a’附加模式,‘r+’读写模式。
如何省略默认是只读模式。
如何写入文件不存在,open()函数会自动创建。
filename = 'programming.txt'
with open(filename, 'w') as file_object: #字符串写入到文件
file_object.write('I love programming')
with open(filename, 'a', encoding='utf8') as file_object: #中文字符串写入到文件
file_object.write('\n我爱祖国')
with open(filename, 'a') as file_object: #数字写入到文件
file_object.write('\n' + str(123456))
10.2.2写入多行
filename = 'programming.txt'
with open(filename, 'w', encoding='utf8') as file_object:
file_object.write('\n我爱祖国')
file_object.write('\n我爱祖国')
file_object.write('\n我爱祖国')
file_object.write('\n' + str(999))
10.2.3附加到文件
使用实参’a’。
练习10.-3:访客
filename = 'guest.txt'
kingnsl = input('请输出你的名字:')
with open(filename, 'a', encoding='utf8') as file_object:
file_object.write('\n' + kingnsl)
练习10-4:访客名单
filename = 'guest_book.txt'
while True:
name = input("请输出你的名字:")
if name == 'q':
break
else:
print(f"你好{name}")
with open(filename, 'a', encoding='utf8') as f:
f.write('\n' + name)
练习10-5:调查
其实10-4的写法就可以,这里是另一种写法
filename = '原因.txt'
responses = []
while True:
response = input("写出你喜欢编程的原因:")
responses.append(response)
continue_poll = input("是否继续填写?(y/n)")
if continue_poll != 'y':
break
with open(filename, 'a', encoding='utf8') as f:
for response in responses:
f.write(f"{response}\n")
10.3异常
10.3.1处理ZeroDivisionError异常
将引发异常的代码包在try-except代码块中
如:
try:
print(5/0)
except ZeroDivisionError:
print("不可以除以0")
常见应用:如提示用户输入错误:
这样程序就可以继续执行,而不是有错误后停止。
print("给我两个数,我来除以它们")
print("输入'q'退出计算。")
while True:
first_number = input("\n输入第一个数:")
if first_number == 'q':
break
second_number = input("\n输入第二个数:")
if second_number == 'q':
break
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("不能除以0")
else:
print(answer)
10.3.5处理FileNotFoundError异常
和ZeroDivisionError类似
如:假设没有alice.txt这个文件
filename = 'alice.txt'
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
print(f"找不到{filename}这个文件")
10.3.6分析文件
方法split() ----根据一个字符串创建一个单词列表
如:我们想知道alice.txt这本书有多少个字
filename = 'alice.txt'
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
print(f"找不到{filename}这个文件")
else:
words = contents.split()
num_words = len(words)
print(f"爱丽丝漫游奇境记一书有{num_words}个字。")
输出:
爱丽丝漫游奇境记一书有29465个字。
[Finished in 0.1s]
10.3.7使用多少个文件
在这里插入代码片def count_words(filename):
"""计算一个文件大致包含多少个单词"""
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
print(f"找不到{filename}这个文件")
else:
words = contents.split()
num_words = len(words)
print(f"{filename}这本书大致有{num_words}个字。")
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little.txt']
for filename in filenames:
count_words(filename)
输出:
alice.txt这本书大致有29465个字。
siddhartha.txt这本书大致有42172个字。
moby_dick.txt这本书大致有215830个字。
找不到little.txt这个文件
[Finished in 0.1s]
使用了try-except代码块,有两个优点:1、避免用户看到traceback错误。2、让程序继续分析能找到其他文件
10.3.8静默失败
pass语句的使用
把上面示例改成:
except FileNotFoundError:
print(f"找不到{filename}这个文件")
改成:
except FileNotFoundError:
pass
如下:
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"{filename}这本书大致有{num_words}个字。")
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little.txt']
for filename in filenames:
count_words(filename)
输出:
alice.txt这本书大致有29465个字。
siddhartha.txt这本书大致有42172个字。
moby_dick.txt这本书大致有215830个字。
[Finished in 0.1s]
10.3.9决定报告哪些错误
适当的使用显示错误,适当的时候静默处理。
练习10-6:加法运算
ValueError异常
print("计算2个数相加")
x = input("输入第一个数:")
y = input("输入第二个数:")
try:
z = float(x) + float(y)
print(f"{x}加{y}等于{z}")
except ValueError:
print("你输入的不是一个数值")
输出:
计算2个数相加
输入第一个数:2
输入第二个数:3
2加3等于5.0
-----------
计算2个数相加
输入第一个数:1
输入第二个数:w
你输入的不是一个数值
练习10-7:加法计算器
print("加法计算器")
while True:
first_number = input("输入第一个数值:")
if first_number == 'q':
break
second_number = input("输入第二个数值:")
if second_number == 'q':
break
try:
answer = int(first_number) + int(second_number)
print(answer)
except ValueError:
print("你输入的不是一个数值")
输出:
加法计算器
输入第一个数值:十
输入第二个数值:五
你输入的不是一个数值
输入第一个数值:10
输入第二个数值:5
15
练习10-8:猫和狗
filenames = ['cats.txt', 'dogs.txt']
for filename in filenames:
try:
with open(filename, encoding='utf-8') as f:
kingnsl = f.read()
print(kingnsl)
except FileNotFoundError:
print(f"找不到文件{filename}")
输出:
小爱猫
猪猪猫
小花猫
找不到文件dogs.txt
[Finished in 0.1s]
练习10-9:静默的猫和狗
filenames = ['cats.txt', 'dogs.txt']
for filename in filenames:
try:
with open(filename, encoding='utf-8') as f:
kingnsl = f.read()
print(kingnsl)
except FileNotFoundError:
pass
输出:
小爱猫
猪猪猫
小花猫
[Finished in 0.1s]
练习10-10:常见单词
方法count()----确定特定的单词或短语在字符串中出现了多少次。
def count_read(filename, word):
"""计算单词在字符串中出现了多少次"""
try:
with open(filename, encoding='utf-8') as f:
contens = f.read()
except FileNotFoundError:
print(f"找不到文件{filename}")
else:
kingnsl = contens.lower().count(word)
msg = f"'{word}'在{filename}中出现了{kingnsl}次" #注意{word}是单引号内
print(msg)
filename = 'alice.txt'
count_read(filename, 'the')
输出:
'the'在alice.txt中出现了2505次
[Finished in 0.1s]
10.4储存数据
模块json(JavaScript Object Notation)
下面示例将一组数字列表,储存以.json扩展名的文件中。我们使用函数json.dump()储存数字列表到文件number.json
json.dump(number, f)它有2个实参。
import json
number = [2,3,5,7,11,13]
filename = 'number.json'
with open(filename, 'w') as f:
json.dump(number, f)
函数json.load() ----读取到内存
import json
filename = 'number.json'
with open(filename) as f:
number = json.load(f)
print(number)
10.4.2保存和读取用户生成的数据
import json
#如果以前储存了用户名,就加载它,否则,提示用户输入用户名并储存它
#这里使用了try-except代码块,当文件不存在时继续执行后面的代码。
filename = 'username.json'
try:
with open(filename) as f:
username = json.load(f)
except FileNotFoundError:
username = input("你叫什么名字:")
with open(filename, 'w') as f:
json.dump(username, f)
print(f"你的用户名是{username}")
else:
print(f"欢迎回来{username}")
思考:这个程序如果第1次打开直接回车,就是个空用户名,如何解决。
如果把生成了username.json文件内容删除,程序会报错:son.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)。
10.4.3重构
先将前面示例写在一个名为:greet_user的函数里
import json
def greet_user():
"""问候用户,并指出其名字"""
filename = 'username.json'
try:
with open(filename) as f:
username = json.load(f)
except FileNotFoundError:
username = input("你叫什么名字:")
with open(filename, 'w') as f:
json.dump(username, f)
print(f"你的用户名是{username}")
else:
print(f"欢迎回来{username}")
greet_user()
这个函数集合了3个功能:1、如果储存了用户名,就获取它。2、当储存了用户名它显示欢迎语。3、当没有文件时候提示用户输入用户名。
重构代码就是把每一个功能单独的用函数表示,以达到单一而清晰的任务。
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 get_new_username():
"""提示用户输入用户名"""
username = input("请输入你的名字:")
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"欢迎回来{username}")
else:
username =get_new_username()
print(f"你的用户名是{username}")
greet_user()
练习10-11:喜欢的数
10-11-1.py
import json
filename = 'user_number.json'
user_number = input("输入你喜欢的数字:")
with open(filename, 'w') as f:
json.dump(user_number, f)
10-11-2.py
import json
filename = 'user_number.json'
with open(filename) as f:
user_number = json.load(f)
print(f"I know favorite number! It's {user_number}")
练习10-12:记住喜欢的数
import json
filename = 'user_number.json'
try:
with open(filename) as f:
user_number = json.load(f)
except FileNotFoundError:
user_number = input("输入你喜欢的数字:")
with open(filename, 'w') as f:
json.dump(user_number, f)
else:
print(f"I know favorite number! It's {user_number}")
练习10-13:验证用户
这个题的关键在于,如果是另一个用户运行了该程序该如何办?因此我们需要在函数def greet_user()加入if判断。
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 get_new_username():
"""提示用户输入用户名"""
username = input("请输入你的名字:")
filename = 'username.json'
with open(filename, 'w') as f:
json.dump(username, f)
return username
def greet_user():
"""问候用户,并指出其名字"""
username = get_stored_username()
if username:
correct = input(f"这{username}是你的用户名吗?(y/n)")
if correct == 'y':
print(f"欢迎{username}回来")
else:
username = get_new_username()
print(f"欢迎{username}回来")
else:
username =get_new_username()
print(f"你的用户名是{username}")
greet_user()