python-10-文件和异常-学习笔记
1.从文件中读取数据
读取整个文件
pi_digits.txt的内容
3.1415926535
8979323846
2643383279
file_reader.py文件内容
open(‘pi_digits.txt’):返回一个表示文件pi_digits.txt的对象
关键字 with:在不再需要访问文件后将其关闭,让Python去确定:使用者只管打开文件,并在需要的时候使用,Python会在适合的时候自动将其关闭。
本程序中使用了open(),却没有调用close(),
人工确定是否打开和关闭文件:调用open()和close(),但这种操作很容易出问题。
'''
open('pi_digits.txt'):返回一个表示文件pi_digits.txt的对象
关键字with:在不再需要访问文件后将其关闭
'''
# 版本1
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)
#版本2
#输出结果和版本1相同,就是删除了末尾空行
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents.rstrip())
#要删除末尾的空行,可在print语句中使用rstrip()
文件路径
路径 | 理解 |
---|---|
相对路径 | 该位置是相对于当前运行的程序(即.py程序文件)所在目录的 ,一般是在同一个目录下的子目录中寻找 |
绝对路径 | 文件在计算机中的准确位置,提供的是完整的路径,相对路径行不通的时候,使用绝对路径 |
注意:在Windows系统中,在文件路径中使用的反斜杠(/),与Linux和OS X系统是不一样的。
举例说明
假设:当程序文件file_reader.py存储在文件夹python_work中,在python_work中,有一个名为text_files的文件夹里存放一个filename.txt。
需要在程序文件中打开filename.txt时使用以下代码:
#方法1:采用相对路径
with open(r"text_files\filename.txt") as file_object:
'''
由于反斜杠\在python中被视为转义标记,为在Windows中确保不出错,应以原始字符串的方式指定路径,即在开头的引号前加上r
'''
contents = file_object.read()
print(contents.rstrip())
#方法2:采用绝对路径
file_path =r'G:\python_work\text_files\filename.txt'
with open(file_path) as file_object:
#----snip----
逐行读取
filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line)
运行结果:
打印每一行时,多了些空白行,其原因是在这个文件中,每行的末尾都有一个看不见的换行符,而print语句也会加上一个换行符。
两个换行符:一个来自文件,一个来自print语句。
要消除多余的空白行,还是采用在print语句中使用rstrip()
#----snip----
for line in file_object:
print(line.rstrip())
运行结果:
创建一个包含文件各行内容的列表
filename = 'pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
# readlines()从文件中读取每一行,并将其存储在一个列表lines中
# 采用for循环打印lines中的各行
for line in lines:
print(line.rstrip())
使用文件的内容
filename = 'pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
# 创建一个变量pi_string用于存储圆周率的值
pi_string = ''
# 采用一个循环将各行都加入pi_string,并删除每行末尾的换行符
for line in lines:
pi_string += line.rstrip()
# 打印字符串及其长度
print(pi_string)
print(len(pi_string))
#----snip----表示相同代码
#----snip----
#将rstrip()改为strip(),不仅删除空行,还删除空格,运行结果见下
for line in lines:
pi_string += line.strip()
#----snip----
包含一百万位的大型文件
filename = 'pi_million_digits.txt'
#----snip----
print(pi_string[:52]+'...')
print(len(pi_string))
圆周率中是否包含你的生日
filename = 'pi_million_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
# 创建一个变量pi_string用于存储圆周率的值
pi_string = ''
for line in lines:
pi_string += line.strip()
# 提示用户输入生日
birthday = input('Enter your birthday, in the form mmddyy: ')
# 用if语句进行判断
if birthday in pi_string:
print('Your birthday appears in the first million digits of pi!')
else:
print('Your birthday does not appears in the first million digits of pi')
运行结果
2、写入文件
写入空文件
相关说明:
调用open()时,可指定读取模式(‘r’)、写入模式(‘w’)、附加模式(‘a’)或能够读取和写入的模式(‘r+’)。
未指定时,Python默认只读模式打开文件。
filename = 'programming.txt'
'''
调用open()时提供了两个实参,
第一个是要打开的文件的名称,
第二个实参('w')是告诉Python,要以写入的模式打开该文件。
'''
with open(filename, 'w') as file_object:
file_object.write('I love programming.')
写入多行
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')
#如果write语句中不加\n换行符,则写入的语句是在同一行的
附加到文件
如果是给文件添加内容,而不是覆盖原有的内容时,以附加模式打开文件。如果此时指定的文件不存在,Python将创建一个空文件。
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 app that can run in a browser.\n')
练习.填写访客名单
filename = 'guest.txt'
while True:
keep_running = input("有访客到来吗?(y/n):")
if keep_running == 'n':
break
s = input('请输入您的姓名:')
with open(filename, 'a') as file_object:
file_object.write(s+'\n')
print(s + "欢迎你的到来!")
3. 异常
处理ZeroDivisionError异常
举例:当一个数字除以0的时候会发生异常错误
使用try-except代码块
将导致错误的代码行放在一个try代码块中,如果try中的代码块运行起来没有问题,Python将跳过except代码块;如果try代码块中的代码导致了错误,Python将查找except代码块,并运行其中的代码,见例1。
如果try-except代码块后面还有其他代码,程序将接着运行,因为已经告诉了Python如何处理这种错误,见例2。
使用try-except-else代码块
在例2中,try中的代码块只包含可能导致错误的代码。依赖于try代码块成功执行的代码都放在else代码块中。
# 例1
try:
print(5 / 0)
except ZeroDivisionError:
print("you can't divide by zero!")
# 例2
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
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by zero!")
#使用else-代码块来打印结果
else:
print(answer)
处理FileNotFoundError异常
当尝试读取一个不存在的文件时,会引发FileNotFoundError异常
filename = 'alice.txt'
with open(filename) as f_obj:
contents = f_obj.read()
异常如下
Traceback (most recent call last):
File "G:/File_test/alice.py", line 3, in <module>
with open(filename) as f_obj:
FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'
在上述示例中,这个错误是open()导致的,因此要处理这个错误,必须将try语句放在包含open()的代码行之前:
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)
Sorry, the file alice.txt does not exist.
分析文本
本节中使用的文本来自项目Gutenberg(http://gutenberg.org/)
title = 'Alice in Wonderland'
print(title.split())
方法split()以空格为分隔符将字符串拆成多个部分,并将这些部分都存储到一个列表中。
['Alice', 'in', 'Wonderland']
首先将alice.txt文件存放到和alice.py同一目录下,然后执行以下代码
filename = 'alice.txt'
try:
with open(filename, encoding='utf-8') as f_obj:
#未加encoding='utf-8'时会出现异常
# ————snip————
else:
# 计算文件大致包含多少个单词
word = contents.split()
num_words = len(word)
print('The file ' + filename + ' has about ' + str(num_words) + ' words.')
未加encoding='utf-8’时出现以下异常时,
Traceback (most recent call last):
File "G:/File_test/alice.py", line 5, in <module>
contents = f_obj.read()
UnicodeDecodeError: 'gbk' codec can't decode byte 0x9d in position 1596: illegal multibyte sequence
参考:
(https://blog.csdn.net/shijing_0214/article/details/51971734)
(https://blog.csdn.net/The_Time_Runner/article/details/92775720)
#正确运行结果
The file alice.txt has about 29608 words.
使用多个文件
代码与上面基本相同,仅将这些代码移到count_words()中,并增加了缩进量。
# 版本1.使用一个文件
def count_words(filename):
'''计算一个文件大概包含多少个单词'''
try:
with open(filename, encoding='utf-8') as f_obj:
contents = f_obj.read()
except FileNotFoundError:
msg = 'Sorry, the file ' + filename + ' does not exist.'
print(msg)
else:
# 计算文件大致包含多少个单词
word = contents.split()
num_words = len(word)
print('The file ' + filename + ' has about ' + str(num_words) + ' words.')
filename = 'alice.txt'
count_words(filename)
# 版本2.使用多个文件
def count_words(filename):
# ————snip————
#其中,dream.txt在word_count.py所在的目录中是没有的
filenames = ['alice.txt', 'dream.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
count_words(filename)
# 版本1.运行结果
The file alice.txt has about 29608 words.
# 版本2.运行结果
The file alice.txt has about 29608 words.
Sorry, the file dream.txt does not exist.
The file siddhartha.txt has about 42166 words.
The file moby_dick.txt has about 215829 words.
The file little_women.txt has about 5594 words.
def count_words(filename):
# ————snip————
filenames = ['alice.txt', 'dream.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
count_words(filename)
失败时一声不吭
当希望程序在发生异常时一声不吭,就像什么都没有发生一样继续运行,采用在try-except-else代码块中使用pass语句。
def count_words(filename):
'''计算一个文件大概包含多少个单词'''
try:
# ————snip————
except FileNotFoundError:
pass
else:
# ————snip————
filenames = ['alice.txt', 'dream.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
count_words(filename)
# 运行结果
The file alice.txt has about 29608 words.
The file siddhartha.txt has about 42166 words.
The file moby_dick.txt has about 215829 words.
The file little_women.txt has about 5594 words.
决定报告哪些错误
自行动手练习——之后再补
4. 存储数据
使用模块 json 来存储数据
使用 json.dump() 和 json.load()
- 第一个程序使用json.dump() 来存储这组数字,第二个程序将使用 json.load()。
- json.dump() 接受两个实参:要存储的数据,以及可用于存储数据的文件对象。
- json.load()加载存储在numbers.json中的信息,并将其存储到变量numbers中。
#number_writer.py文件
import json
numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json'
with open(filename, 'w') as f_obj:
json.dump(numbers, f_obj)
#number_reader.py文件
#使用json.load()将列表numbers读取到内存中
import json
filename = 'numbers.json'
with open(filename) as f_obj:
numbers = json.load(f_obj)
print(numbers)
保存和读取用户生成的数据
再次说明:变量filename表示的并非实际文件,它只是一个让Python知道到哪里去查找文件的字符串,因此可以轻松的将’username.json’替换为要使用的另一个文件的名称。
# remember_me.py文件
import json
username = input('What is your name?\n')
filename = 'username.json'
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
print("We'll remember you when you come back, " + username + "!")
# greet_user.py文件
import json
filename = 'username.json'
with open(filename) as f_obj:
username = json.load(f_obj)
print("Welcome back, " + username +"!")
# remember_me.py文件运行结果
What is your name?
Alice
We'll remember you when you come back, Alice!
# greet_user.py文件运行结果
Welcome back, Alice!
尝试将remember_me.py和greet_user.py合并到一个程序(remember_me.py)中
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?\n')
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 + "!")
重构
import json
def greet_user():
'''问候用户,并指出其名字'''
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
username = input('What is your name?\n')
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 + "!")
greet_user()
重构greet_user()
import json
def get_stored_username():
''' 如果存储了用户名,就获取它'''
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
return None
else:
return username
#新增一个函数greet_user()
def greet_user():
'''问候用户,并指出其名字'''
username = get_stored_username()
if username:
print("Welcome back, " + username + "!")
else:
username = input('What is your name?\n')
filename = 'username.json'
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
print("We'll remember you when you come back, " + username + "!")
greet_user()
继续优化上叙代码,将greet_user()中的另一个代码块提取出来:将没有存储用户名时,提示用户输入的代码放在一个独立的函数中:
import json
def get_stored_username():
''' 如果存储了用户名,就获取它'''
#————snip————
def get_new_username():
'''提示用户输入用户名'''
username = input('What is your name?\n')
filename = 'username.json'
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
return username
def greet_user():
'''问候用户,并指出其名字'''
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()
本文地址:https://blog.csdn.net/sinat_36183354/article/details/107119853