目录
一、从文件中读取数据
1.1 读取整个文件
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)
- 函数open()接受一个参数:要打开的文件的名称。Python在当前执行的文件所在的目录中查找指定的文件,函数open()返回一个表示文件的对象,并将此对象存储在变量file_object中。
- 关键字with在不再需要访问文件后将其关闭。并非在任何情况下都能轻松确定关闭文件的恰当时机,但是通过with结构,可以让Python去确定,用户只管打开文件,并在需要的时候使用它,Python会在何时的时候自动将其关闭;
- 方法read()用来读取文件的全部内容,并将其作为一个长长的字符串存储在变量contents中,通过打印contents的值,就可将这个文本文件的全部内容显示出来;
- 相比于原文件,该输出的不同在于末尾多了一个空行,因为read()到达文件末尾时返回一个空字符串,而将这个空字符串显示出来就是一个空行,要删除多余的空行,应使用rstrip(),此时输出与原始文件的内容完全相同。
print(contents.rstrip())
1.2 文件路径
- 相对路径——数据文件存储在程序文件所在目录下的一个文件夹中
- 绝对路径——使用绝对路径乐意读取系统任何位置的文件
MAC OS使用“/”,windows 使用“\”。
1.3 逐行读取
读取文件时,常常需要检查其中的每一行:可能要在文件中查找特定的信息,或者以某种方式修改文件中的文本。
要以每次一行的方式检查文件,可对文件对象使用for循环:
filename = 'txt_file/pi_digist.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
- 可以将要读取文件的名称存储在变量filename中;
- 调用open()后,将一个表示文件及其内容的对象存储到了变量file_object中;
- 使用关键字with,让Python负责打开和关闭文件。
1.4 创建一个包含文件各行内容的列表
使用关键字with时,open()返回的文件对象只在with代码块内可用,要在with代码块外访问文件的内容,可在with代码块内将文件的各行存储在一个列表中,并在with代码块外使用该列表。
filename = 'txt_file/pi_digist.txt'
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
1.5 使用文件的内容
e.g 以简单的方式使用圆周率的值。
filename = 'pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
print(pi_string)
print(len(pi_string))
!!读取文本时,Python将其中的所有文本都解读为字符串,若读到的是数字并要将其作为数值使用,就必须使用函数int()将其转换为整数,或使用float()将其转换为浮点数。
1.6 包含一百万位的大型文件
对于可处理的数据量,Python没有任何限制,只要系统的内存足够做,想处理多少数据都可以。
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(pi_string[:52] + '...')
print(len(pi_string))
1.7 圆周率中包含你的生日吗
e.g 判断某人的生日是否包含在圆周率值的前10000001位中。(可将生日表示位一个?️数字组成的字符串,再检查这个字符串是否包含在pi_string中。
filename = 'pi_million_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.rstrip()
birthday = input("Enter your birthday, in the form mmddyy:")
if birthday in pi_string:
print("Your birthday appears in the first million digits of pi!")
else:
print("Your birthday does not appear in the first million digits of pi.")
练习:
e.g-1 在文本编辑器中新建一个文件,命名为“learning_python.py”;编写一个程序,读取该文件,并打印其内容。
filename = 'learning_python.txt'
with open(filename) as file_object:
# 读取整个文件
contents = file_object.read()
print(contents.rstrip())
# 遍历文件对象
for line in file_object:
print(line.strip())
# 将各行存储在一个列表中
lines = file_object.readlines()
# 在with代码块外打印文件内容
for line in lines:
print(line.strip())
e.g-2 使用方法replace()将字符串中的特定单词都替换为另一个单词。
message = "I really like dogs, I hace a dog named 'Pipi'."
print(message.replace('dog','cat'))
二、写入文件
保存数据最简单的方式之一是将其写入文件中。通过将输出写入文件,即便关闭包含程序输出的终端窗口,这些输出也依然存在。
2.1 写入空文件
filename = 'programming.txt'
with open(filename,'w') as file_object:
file_object.write("I love programming!")
- 写文件时调用open()需要提供两个实参,一个是文件名,另一个是'w'告诉Python以写入模式打开文件。打开文件时,可以指定“读取模式('r'),写入模式('w'),附加模式('a'),能够读取和写入文件的模式('r+)。若忽略了模式实参,Python将以默认的只读模式打开文件;
- 若写入的文件不存在,open()将自动创建;若以写入模式('w')打开文件,指定的文件已经存在,python将在返回文件对象前清空该文件。
- Python只能将字符串写入文本文件中,要将数值数据存储到文本文件中,必须先使用函数str()将其转换为字符串格式。
2.2 写入多行
函数write()不会在写入文本末尾的换行符,需要指定换行符。\n——换行符,\t——制表符
with open(filename,'w') as file_object:
file_object.write("I love programming.\n")
file_object.write("I love creating new games.\n")
2.3 附加到文件
若要给文件添加内容,而不是覆盖原有的内容,可以使用附加模式打开文件;以附加模式打开文件时,Python不会在返回文件对象前清空文件,写入的内容将加在文件的末尾;若打开的指定文件不存在,Python会创建一个空文件。
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 browser.\n")
练习
e.g 编写一个while循环,提示用户输入其名字。用户输入其名字后,在屏幕上打印一句问候语,并将一条访问记录添加到文件guest_book.txt中,确保每条记录都独占一行。
filename = 'guest_book.txt'
flag = True
with open(filename,'w') as file_object:
while flag:
name = input("Please input your name: ")
if name!='q':
message = "Hello, " + name.title()
print(message)
file_object.write(message + "\n")
else:
break
三、异常
Python使用被称为异常的特殊对象来管理程序执行期间发生的错误,每当发生让Python无法处理的错误时,它会创建一个异常对象;若编写了处理该异常的代码,程序将继续运行,若未对异常进行处理,程序将停止,并显示traceback,其中包含有关异常的报告。
异常是使用try-except代码块处理的,try-except代码块让python执行指定的操作,同时告诉Python发生异常时该怎么办。使用try-except代码块时,即便出现异常程序也会继续运行,显示编写好的错误信息而不是traceback。
3.1 处理ZeroDivisionError异常
当认为可能发生了错误时,可编写一个try-except代码块来处理可能引发的异常。
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
- 将可能导致错误的代码行放在try 代码块中,如果try 代码块运行期俩没有问题,Python将跳过except代码块,如果try代码块中的代码导致了错误,Python将查找昂except代码块,并运行其中的代码,指出引发错误的原因。
- 若try-except代码块后面还有其他代码,程序将接着运行。
3.2 使用异常避免崩溃
发生错误时,若程序还没有完成工作,妥善得处理错误异常重要。这种情况常常出现在要求用户提供输入的程序中,如果程序能够妥善地处理无效输入,就能再提示用户有效输入,而不至于崩溃。
e.g 创建一个只执行除法运算的简单计算器。
print("Give me two number 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)
try-except-else代码块的工作原理:
- 只有可能引发异常的代码才需要放在try语句中;
- 仅在try代码块中成功执行时才需要运行的代码,放在else代码块中;
- except代码块指示了当try代码块中的代码引发了指定的异常时,程序应该怎么做。
3.3 处理FileNotFoundError异常
e.g 尝试读取一个不存在的文件。
filename = 'programming.txt'
try:
with open(filename) as file_object:
contents = file_object.read()
print(contents)
except FileNotFoundError:
msg = "Sorry, the file '" + filename + "' does not exist."
print(msg)
3.4 分析文本
split():以空格为分割符将字符串拆分成多个部分,并将这些部分都存储在一个列表中,结果是一个包含字符串中所有单词的列表。
e.g 分析文本中包含多少单词。
try:
with open(filename) as file_object:
contents = file_object.read()
except FileNotFoundError:
msg = "Sorry, the file '" + filename + "' does not exist."
print(msg)
else:
# 计算文件大致包含多少单词
words = contents.split()
num_words = len(words)
print("The file " + filename + " has about " + str(num_words) + " words.")
3.5 使用多个文件
def count_words(filename):
"""计算一个文件大致包含多少个单词"""
try:
with open(filename) as f_obj:
contents = f_obj.read()
except FileNotFoundError:
msg = "Sorry, the file '" + filename +"' does not exist.."
print(msg)
else:
# 计算文件大致包含几个单词
words = contents.split()
num_words = len(words)
print("The file " + filename + " has about " + str(num_words) + " words.")
filenames = ['alice.txt','siddhartha.txt','moby_dick.txt','little_women.txt']
for filename in filenames:
count_words(filename)
3.6 pass()语句
pass语句可以跳过,也可以做占位符,提醒用户在程序的某个地方什么都没做,并且以后也许要在这里做些什么。
四、 存储数据
模块json能将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。还可以使用json在Python之间分享数据。Json数据并非Python专用。
4.1 使用json.dump()和json.load()
json.dump()接受两个实参:要存储的数据、可用于存储数据的文件对象。
import json
numbers = [2,3,5,7,11,13]
filename = 'number.json'
with open(filename,'w') as f_obj:
json.dump(numbers,f_obj)
使用json.load()将数据读取到内存中。
import json
filename = 'number.json'
with open(filename) as f_obj:
numbers = json.load(f_obj)
print(numbers)
4.2 保存和读取用户生成的数据
import json
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
username = input("What is 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 +"!")