文件、异常和存储数据
一、文件
1、从文件中读取数据
我们首先简单看一下下面会使用到的文件
’pi_digits.txt’
’pi_million_digits’
从当前文件目录件中读取数据:
with open('pi_digits.txt') as file_object:
"""
关键字with 在不再需要访问文件后将其关闭(不需要使用close())
"""
contents = file_object.read() # 为read() 到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行
print(contents.rstrip()) # rstrip()方法删除字符串末尾的空白
- 关键字with在不再需要访问文件后将其关闭(即不需要调用close()即可关闭文件)。
- read() 到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一 个空行。要删除多出来的空行,可在print语句中使用rstrip() 。
从其他文件目录件中读取数据:
# 相对路径
with open('text_files/filename.txt') as file_object:
...
...
...
# 绝对路径
file_path = '/home/ehmatthes/other_files/text_files/filename.txt'
with open(file_path) as file_object:
...
...
...
- 相对路径:指当前文件目录下的子文件或文件目录。
- 绝对路径:指文件的实际具体位置。
注意:Python里的文件目录分隔符是" / “,而不是” \ "。
逐行读取文件:
file_name = 'pi_digits.txt'
with open(file_name) as file_object:
for line in file_object: # 因为在这个文件中,每行的末尾都有一个看不见的换行符,
print(line.rstrip()) # 而print 语句也会加上一个换行符,因此每行末尾都有两个换行符:一个来自文件,另一 个来自print语句。
在with代码块外使用open返回的对象(语法上是只可以在with里用的):
file_path = 'text_files/pi_digits.txt' # 相对路径
with open(file_path) as file_object:
lines = file_object.readlines() # 方法readlines() 从文件中读取每一行,并将其存储在一个列表中;
# 接下来,该列表被存储到变量lines 中;在with 代码块外,我们依然可以使用这个变量。
for line in lines:
print(line.rstrip())
- 方法readlines() 从文件中读取每一行,并将其存储在一个列表中;接下来,该列表被存储到变量lines中;这样,在with代码块外,我们依然可以使用这个变量。
使用文件中的内容:
将圆周率的前50位打在一行:
# #使用文件的内容
file_path1 = 'E:/Learn_code/Python/learnPython/text_files/pi_million_digits.txt' # 绝对路径
with open(file_path1) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip() # 每行左边的空格,为删除这些空格,可使用strip()
print(pi_string[:52] + "...") # 打印到小数点后50位
print(len(pi_string))
Test:圆周率中包含你的生日吗
下述代码中的pi_string为上面代码得到的。
# #小测试(圆周率中包含你的生日吗)
birthday = input("Enter you birthday,in the form like mmdd:")
if birthday in pi_string:
print("Your birthday appears in the first million digits of pi!")
else:
print("our birthday does not appear in the first million digits of pi.")
2、写入文件
调用open() 时提供了两个实参。第一个实参是要打开的文件的名称;第二个实参(‘w’ )告诉Python,我们要以写入模式打开这个文件。
打开文件时,可指定:
- 读取模式 (‘r’ )
- 写入模式 (‘w’ )、
- 附加模式 (‘a’ )
- 读取和写入文件的模式(‘r+’ )。
如果你省略了模式实参,Python将以默认的只读模式打开文件。
如果你要写入的文件不存在,函数open() 将自动创建它。
然而,以写入(‘w’ )模式打开文件时千万要小心,因为如果指定的文件已经存在,Python将在返回文件对象前清空该文件。
注:python只能将字符串写入文本文件。要存储数值数据,需要使用str()
示例:
filename = 'programming.txt' # 没有该文件 所以python会新创建一个这么文件
with open(filename, 'w') as file_object:
file_object.write("I love programming.")
file_object.write("That's a great thing.\n") # 并不会另起一行写在文件中,另起一行需要换行符
file_object.write("I love creating new games.\n")
# 如果你要给文件添加内容,而不是覆盖原有的内容,可以附加模式打开文件
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")
示例结果:
二、异常
Python使用被称为异常的特殊对象来管理程序执行期间发生的错误。
1、try-except代码块
代码块功能:
当你认为可能发生了错误时,可编写一个try-except 代码块来处理可能引发的异常。如果try 代码块中的代码运行起来没有问题,Python将跳过except 代码块;如果try代码块中的代码导致了错误,Python将查找这样的except代码块,并运行其中的代码,即其中指定的错误与引发的错误相同。
示例:
try:
print(5/0)
except ZeroDivisionError:
print("You cannot divided by 0!")
运行此代码块结果如下:
可以看出并不会引发错误,Python将跳过try里面的内容,执行except语句内容。
try-except-else 代码块:
发生错误时,如果程序还有工作没有完成,妥善地处理错误就尤其重要。这种情况经常会出现在要求用户提供输入的程序中;如果程序能够妥善地处理无效输入,就能再提示用 户提供有效输入,而不至于崩溃。
通过将可能引发错误的代码放在try-except-else代码块中,可提高这个程序抵御错误的能力。
示例:
print("Give me 2 numbers,and I will divide them.")
print("Enter 'q' to quit.")
while True:
first_number = input("\nFirst number: ")
if first_number == 'q':
break
second_number = input("Second number: ")
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You cannot divided by 0!")
else:
print(answer)
结果如下:
2、处理FileNotFoundError 异常
文件名不存在、文件名或目录错误会引发FileNotFoundError错误。
eg: 打开一个不存在的文件:
# ##FileNotFoundError异常(文件名不存在或者文件名或目录错误)
filename = 'yb.txt' # 一个不存在的文件
try:
with open(filename) as file_object:
contents1 = file_object.read()
except FileNotFoundError:
print("Sorry,the file " + filename + " does not exist.")
结果如下:Test:分析文本(包含多少word)
# ##分析文本
def count_words(internal_file_name):
"""计算一个文本文件大致包含多少单词"""
try:
with open(internal_file_name) as file_obj:
contents2 = file_obj.read()
except FileNotFoundError:
print("Sorry,the file " + internal_file_name + " does not exist.")
else: # 计算文件中大致包含多少单词
words = contents2.split()
num_words = len(words)
print("The file " + internal_file_name + " has about " + str(num_words) +
" words.")
file_names = ['text_files/text1.txt', 'text_files/text2.txt',
'text_files/text3.txt', 'text_files/text4.txt']
for file_name in file_names:
count_words(file_name)
其中,text1、2、3、4是4个文本文件,里面是词语数量不等的。
2、失败时一声不吭
有时候你希望程序在发生异常时一声不吭,就像什么都没有发生一样继续运行。 要让程序在失败时一声不吭,可像通常那样编写try 代码块,但在except 代码块中明确地告诉Python什么都不要做。在except语句中使用pass即可。
def count_words(filename): """计算一个文件大致包含多少个单词"""
try:
--snip -
except FileNotFoundError:
pass
else:
--snip -
三、存储数据
1、json模块
很多程序都要求用户输入某种信息,如让用户存储游戏首选项或提供要可视化的数据。不管专注的是什么,程序都把用户提供的信息存储在列表和字典等数据结构中。用户关闭程序时,你几乎总是要保存他们提供的信息;一种简单的方式是使用模块json来存储数据。
使用json.dump()存储:
- 函数json.dump() 接受两个实参:要存储的数据以及可用于存储数据的文件对象。
使用 json.load加载:
- 函数json.loadd() 接受一个实参:存储数据的文件对象
存储和加载演示:
import json
# 存储
numbers_store = [1, 2, 3, 4, 5]
filename = 'numbers.json'
with open(filename, 'w') as f_obj:
json.dump(numbers_store, f_obj)
# 加载
with open(filename) as f_obj:
numbers_load = json.load(f_obj)
print(numbers_load)
- 该代码将生成一个number.json文件,并在其中存储数组。最后加载该文件,将数组输出。
- 通常使用文件扩展名 .json来指出文件存储的数据为JSON格式。
2、保存和读取用户生成的数据
一个记住我的小程序:
# 如果以前存储了用户名就加载它
# 否则就提示用户输入用户名并存储它
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
username = input("What's your name? ")
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
print("We'll remember you when you come back, " + username + "!")
else:
print("Welcome back, " + username + "!")
3、重构
概念:
—将代码划分为一系列完成具体工作的函数。这样的过程被称为重构。
使用函数完成上述’’‘记住我’’'的小程序,见下:
import json
def get_stored_username():
"""Get stored username if available."""
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
return None
else:
return username
def get_new_username():
"""Prompt for a new username."""
username = input("What is your name? ")
filename = 'username.json'
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
return username
def greet_user():
"""Greet the user by name."""
username = get_stored_username()
if username:
print("Welcome back, " + username + "!")
else:
username = get_new_username()
print("We'll remember you when you come back, " + username + "!")
greet_user()
注意:
上面在二.2讲解了FileNotFoundError :文件名不存在、文件名或目录错误会引发。但是,又在一.2写入文件的代码示例中,说不存在该文件时会自动创建一个。这两者并不矛盾,在能自动创建一个文件的前提,是需要使用 ‘w’ 模式,即写入模式才可以。否则就会引发FileNotFoundError错误。