- 文件,让程序能够快速分析大量数据。
- 异常是python创建的特殊对象,用于管理程序运行时出现的错误。
- 模块json,让你能够保存用户数据,以免在程序停止运行后丢失。
从文件中读取数据
1.读取整个文件
- python在当前执行文件所在的目录中查找指定的文件。
- 关键字With在不再需要文件后将其关闭。你只管打开文件,并在需要时使用它,python会在合适的时候自动将其关闭。
read()
方法读取这个文件的全部内容。
with open('pi_digits.txt') as file_object:
contents=file_object.read()
print(contents)
函数open()
接受一个参数,要打开的文件的名称。
open('pi_digits.txt')
返回一个表示文件pi_digits.txt的对象,python将这个对象存储在我们将在后面使用的变量中。
print(contents.rstrip)
read()到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行,要删除末尾的空行,可以在print语句中使用rstrip().
2.文件路径
with open('text_files\filename.txt') as file_object:
让python到文件夹text_files中去查找指定的.txt文件。- 绝对文件路径,文件在计算机中的准确位置,绝对路径通常比相对路径长,因此将其存储在一个变量中,再将该变量传递给open()会有所帮助。
- 在Windows中为确保万无一失,应以原始字符串的方式指定路径,即在开头的单引号前加r。
3.逐行读取
- 要以每次一行的方式检查文件,可对文件对象使用for循环。
filename='pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
11111
222222
333333
文件每行末尾会有一个看不见的换行符,而且print也会加上一个换行符,为消除这些多余的空白行,可在print语句使用rstrip()
4.创建一个包含文件各行内容的列表
- 使用关键字with时,open()返回的文件对象只在with代码块内可用,如果要在with代码块外访问文件的内容,可在with代码块内将文件的各行存储在一个列表中,并在with代码块外使用该列表:可以立即处理文件的各个部分,也可推迟到程序后面再处理。
filename='pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
readlines()
从文件中读取每一行,并将其存储在一个列表中,接下来,该列表被存储到变量lines中,在with代码块外,我们依然可以使用这个变量。
5.使用文件的内容
- 将文件读取到内存后,就可以以任何方式使用这些数据了。
- 读取文件时,python将其中的所有文本都解读为字符串。
filename='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))
打开文件,将其中的所有行都存储到一个列表中,变量
pi_string
用于存储文件中的内容,使用一个循环将各行都加入到pi_string,并使用rstrip()
删除每行末尾的换行符,然后再打印这个列表以及列表的长度。
10-2 C语言学习笔记
filename='pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip().replace('python','c'))
写入文件
1.写入空文件
- 要将文本写入文件,在调用
open()
时需要提供一个实参,告诉python你要写入打开的文件。 - 以
写入'w'模式
打开文件时,如果指定的文件已经存在,python将在返回对象前清空该文件。
finename='pi_digits.txt'
with open(finename,'w') as file_object:
file_object.write('wenwen')
调用open()提供两个实参,第一个实参是要打开的文件名称,第二个实参
w
告诉python我们要以写入模式打开这个文件。打开文件时,可以指定读取模式‘r'
,写入模式'w'
,附加模式'a'
,能够读取和写入文件的模式'r+'
,如果省略模式实参,python以默认的只读模式打开文件。
2.写入多行
- 要让每个字符串都单独占一行,需要在write()语句中包含换行符。
finename='pi_digits.txt'
with open(finename,'w') as file_object:
file_object.write('I love my life.\n')
file_object.write('I love my lover.\n')
附加到文件
- 如果要添加文件,而不是覆盖原有的内容,可以附加模式打开文件,以这种模式打开文件时,python不会在返回文件对象前清空文件,而你写入到文件的行都将添加到文件末尾,如果指定的文件不存在,python将会为你创建一个空文件。
finename='pi_digits.txt'
with open(finename,'a') as file_object:
file_object.write('I fell happy now.\n')
file_object.write('I love my boyfriend.')
打开文件时指定实参
a
,以便将内容附加到文件末尾,而不是覆盖文件原来的内容。
10-4访客名单
filename = 'guest.txt'
while True:
name = input("请输入你的名字:")
if name =='q':
break
with open(filename,'a') as file_object:
file_object.write(name)
file_object.write('\n')
异常
1.处理ZeroDivisionError
- 将一个数字除以0,就会引发这个错误。
- 在这种错误中,
ZeroDivisionError
是一个异常对象,在这种情况下,python停止运行程序,指出发生哪种异常,我们可根据提示对程序进行修改。
2.使用try-except代码块
- 认为可能发生了错误时,使用try-except代码块来处理可能引发的异常。
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero.")
如果try代码块中的代码运行起来没有问题,python将跳过except代码块;如果try代码块中的代码导致了错误,python将查找这样的except代码块,并运行其中的代码,即指定的错误与引发的错误相同。
3.使用异常避免崩溃
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("\nSecond 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 "D:/python/untitled/ten/division.py", line 18, in <module>
answer = int(first_number)/int(second_number)
ZeroDivisionError: division by zero
4.else代码块
- 通过将可能引发错误的代码放在try-except代码块中,可提高这个程序抵御错误的能力。
- 依赖于try代码块成功执行的代码块都应放到else代码块中。
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("\nSecond number:")
try:
answer = int(first_number)/int(second_number)
except ZeroDivisionError:
print("You can't divide by 0!")
else:
print(answer)
try-except-else
代码块的工作原理:
- python尝试执行try代码块中的代码。
- 只有可能引发异常的代码才需要放在try语句中
- 有一些仅在try代码块成功执行时才需要运行的代码,这些代码要放在else代码块中。
- except代码块告诉python,如果它尝试运行try代码块中的代码时引发了指定的异常,该怎么办。
5.处理FileNotFoundError异常
- 找不到文件时,可以使用try-except代码块以直观的方式进行处理。
尝试读取一个不存在的文件
filename='alice.txt'
with open(filename) as f_obj:
contents=f_obj.read()
Traceback (most recent call last):
File "D:/python/untitled/ten/division.py", line 26, in <module>
with open(filename) as f_obj:
FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'
将其放在try-except代码块中:
filename='alice.txt'
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.")
对变量
contents
调用方法split()
,以生成一个列表,其中包含这个文件中的所有单词,使用len()
来确定这个列表的长度。
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','pi_digits.txt','guest.txt','abc.txt']
for filename in filenames:
count_words(filename)
The file alice.txt has about 6 words.
The file pi_digits.txt has about 16 words.
The file guest.txt has about 3 words.
Sorry,the file abc.txt does not exist.
8.失败时一声不吭
- python有一个pass语句,可在代码块中使用它来让python什么都不做。
def count_words(filename):
"""计算一个文件大致包含多少个单词"""
try:
with open(filename) as f_obj:
contents = f_obj.read()
except FileNotFoundError:
pass
else:
# 计算文件大致包含多少个单词
words = contents.split()
num_words = len(words)
print("The file " + filename + " has about " + str(num_words) + " words.")
filenames = ['alice.txt','pi_digits.txt','guest.txt','abc.txt','lla.txt']
for filename in filenames:
count_words(filename)
The file alice.txt has about 6 words.
The file pi_digits.txt has about 16 words.
The file guest.txt has about 3 words.
出现
FileNotFoundError
异常时,将执行except
代码块中的代码,但什么都不会发生,这种错误发生时,不会出现traceback,也没有任何输出。用户将看到存在的每个文件包含多少个单词,但是没有任何迹象表明有一个文件未找到。
存储数据
- 使用json模块来存储数据。
模块json
能够将简单的python数据结构存储到文件中,并在程序再次运行时加载该文件中的数据。
1.使用json.dump()和json.load()
- 存储一组数字的简短程序使用
函数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
来指出文件存储的数据为JSON格式。
使用json.load()将这个列表读取到内存中
import json
filename='number.json'
with open(filename) as f_obj:
numbers=json.load(f_obj)
print(numbers)
filename='number.json'
是为了确保读取的是前面写入的文件。以读取方式打开这个文件,使用函数json.load()
加载存储在number.json
中的信息,并将其存储到变量numbers中。
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 +"!")
用户首次运行这个程序时,文件
username.json
不存在,将引发FileNotFoundError
异常,因此python将执行except
代码块。提示用户输入用户名,再使用json.dump()
存储该用户名,并打印一句问候语。
3.重构
- 重构: 代码可以正确运行,但可以做进一步改进,将代码划分为一系列完成具体工作的函数。
- 如果想要重构remem_me.py,可将其大部分逻辑放到一个或多个函数中。
import json
def get_sorted_username():
"""如果存储了用户名,就获取它"""
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():
"""提示用户输入用户名"""
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():
"""问候用户,并指出其名字"""
username = get_sorted_username()
if username:
print("welcome back, " + username +"!")
else:
username = get_new_username()
print("We'll remember you when you come back, " + username +"!")
greet_user()
使用重构,让每个函数都执行单一而清晰的任务。
10-13 验证用户
import json
def get_sorted_username():
"""如果存储了用户名,就获取它"""
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():
"""提示用户输入用户名"""
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():
"""问候用户,并指出其名字"""
username = get_sorted_username()
if username:
your_name=input("Is the name:"+username+", True/False")
if your_name=='True':
print("welcome back, " + username +"!")
else:
username = get_new_username()
print("We'll remember you when you come back, "+username +"!")
else:
username = get_new_username()
print("We'll remember you when you come back, " + username +"!")
greet_user()