python学习10之文件读写

10 文件和异常

10.1 从文件中读取数据

10.1.1 读取整个文件

若要以任何方式使用文件,都得先打开文件,才能访问它。函数open()接受一个参数:要打开的文件名称。关键字with在不需要访问文件后将其关闭
with open('pi_digits.txt') as file_object:
    content1 = file_object.read()#打印出来会发现文件内容末尾多出一个空行,因为read()到达文件末尾时返回一个空字符串,这个空字符串显示出来时就是一个空行
print(content1.rstrip())#加rstrip()删除空行

10.1.2 打开不在当前目录下的文件

with open('../otherFiles/YZU_english.txt') as file_object:#相对路径行不通时可以使用绝对路径,注意这里文件路径的斜杠
    content2 = file_object.read()
print(content2)

当文件名称较长时,可以将其赋给一个变量,再将该变量传递给open()
file_path = '../FileRecv/YZU_english.txt'
# file_path = '..\FileRecv\YZU_english.txt'
# 直接复制windows系统里的路径是错误的,反斜杠\是转义字符。将对字符串中的字符进行转义。
with open(file_path) as file_object:
    content3 = file_object.read()
print(content3)
# 如果一定要使用反斜杠,可对路径中的每一个反斜杠都进行转义
file_path2 = 'C:/Users/35199/Document/Tencent Files/xxx/FileRecv/YZU_english.txt'
# file_path2 = 'C:\\Users\\35199\\Document\\Tencent Files\\xxx\\FileRecv\\YZU_english.txt'  #也是正确的
with open(file_path) as file_object:
    content4 = file_object.read()
print(content4)
如果一定要使用反斜杠,可对路径中的每一个反斜杠都进行转义
file_path2 = 'C:/Users/35199/Document/Tencent Files/xxx/FileRecv/YZU_english.txt'
# file_path2 = 'C:\\Users\\35199\\Document\\Tencent Files\\xxx\\FileRecv\\YZU_english.txt'  #也是正确的
with open(file_path) as file_object:
    content4 = file_object.read()
print(content4)

10.1.3 逐行读取

以每次一行的方式检查文件,可对文件对象使用for循环
file_name = '..\\otherFiles\\YZU_english.txt'
with open(file_name) as file_object:
    for line in file_object:
        print(line.rstrip())#打印时,发现多出很多空白行。因为在这个文件中,每行的末尾都有一个看不见的换行符,调用print()时又会加上一个换行符
        #因此没放后面有两个换行符
        #要消除多余的换行符,用rstrip()

10.1.4 创建一个包含文件各行内容的列表

list = []
file_path = '..\\otherFiles\\YZU_english.txt'
with open(file_path) as file_object:
    for line in file_object:
        list.append(line.rstrip())
print(list)
print(len(list))
正确方式!
readlines()从文件中读取每一行,并将其存储在一个列表中。
with open(file_path) as file_object:
    lines = file_object.readlines()
for line in lines:
    print(line.rstrip())
# print(type(lines)) #list类型

10.1.5 使用文件内容

file_path = '.\\pi_digits.txt'
with open(file_path) 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()将其转换为浮点数。

10.1.6 包含一百万位的大型文件

file_path = '..\\otherFiles\\chapter_10\\pi_million_digits.txt'
with open(file_path) as file_object:
    lines = file_object.readlines()
temp_string = ''
for line in lines:
    temp_string += line.strip()
print(f"temp_string[:52]")# 只打印到小数点后50位,以免终端为显示全部1000 000 位而不断滚动
print(len(temp_string))
temp = temp_string[:52]
print(len(temp))

10.1.7 圆周率中包含你的生日吗

#接10.1.6部分代码
# birthday = '19991230'
birthday = input('Please, input your birthday: ')
if birthday in temp_string:
    print(True)
else:
    print(False)

########################################practice##################################################
# 1.
print('\nquestion1.1')
file_path3 = '..\\otherFiles\\learning_python.txt'
#第一次打印时读取整个文件
with open(file_path3) as file_object:
    content5 = file_object.read()
print(content5.rstrip())
print('\nquestion1.2')
#第二次打印时遍历文件对象
with open(file_path3) as file_object:
    for line in file_object:
        print(line.rstrip())
print('\nquestion1.3')
# 第三次打印时将各行存储在一个列表中,再在with代码块外打印他们
with open(file_path3) as file_object:
    lines = file_object.readlines()
# print(lines)
for line in lines:
    print(line.rstrip())
# 2.
# replace()方法将字符串中的特定单词都替换为另一个单词
print('\nquestion2')
with open(file_path3) as file_object:
    lines = file_object.readlines()
for line in lines:
    if 'dog' in line:
        print(True)
        temp = line.replace('dog','cat')
        lines.remove(line)
        lines.append(temp)
        print(line)
    else:
        print(False)
print(lines)

10.2 写入文件

10.2.1 写入空文件

将文本写入文件,在调用open()时需要提供另一个实参,告诉python你要写入。提供实参‘w’,告诉python以写入模式打开这个文件
w写入模式
a附加模式
r+读写模式
如果省略了模式实参,Python将以默认的只读模式打开文件
如果要写入的文件不存在,open()函数将自动创建它

** 特别注意:**

1.以w模式打开文件,如果文件已经存在,python将在返回文件对象前清空该文件的内容。即清空原文件内容,重新写入。

2.python只能将字符串写入文本文件中。如果要将数值数据存储到文本文件中,必须先使用str()将其转换为字符串格式

file_name2 = '..\\otherFiles\\chapter_10\\programming.txt'
with open(file_name2,'w') as file_object:
    file_object.write("I love programming.1")

10.2.2 写入多行

write()函数不会在写入的文本末尾添加换行符,因此如果写入多行时没有指定换行符,文件看起来可能不是你希望的那样
file_name3 = '..\\otherFiles\\chapter_10\\programming.txt'
with open(file_name2,'w') as file_object:
    file_object.write("I love programming.2")
    file_object.write("I love creating new games.2")

file_name3 = '..\\otherFiles\\chapter_10\\programming.txt'
with open(file_name2,'w') as file_object:
    file_object.write("I love programming.3\n")
    file_object.write("I love creating new games.3\n")

10.2.3 附加到文件

如果要给文件添加内容,而不是覆盖原有的内容,可以以附加模式a打开文件。以附加模式打开文件时,将内容附加到文件末尾,而不是覆盖文件原来的内容
即原文件内容还在,后面则是刚添加的内容
file_name3 = '..\\otherFiles\\chapter_10\\programming.txt'
with open(file_name2,'a') as file_object:
    file_object.write("I love programming.4\n")
    file_object.write("I love creating new games.4\n")
################################################practice##################################################################
# 2.1
# 提示用户输入名字。用户做出响应后,将其名字写入文件guest.txt中
file_name4 = '..\\otherFiles\\chapter_10\\guest.txt'
flag = True
prompt = 'Please, input your name.\n'
prompt += 'otherwise, input q/Q to stop this program:'
while flag:
    message = input(prompt)
    if message.lower() != 'q':
        print(f"Hello, {message}")
        with open(file_name4,'a') as file_object:
            file_object.write(message+'\n')
    else:
        flag = False
# 2.2
# 编写一个while循环,询问用户为何喜欢编程
file_name5 = '..\\otherFiles\\chapter_10\\reasons.txt'
flag = True
prompt = 'Why do you like programming?'
prompt += '\nOtherwise, enter q/Q to stop this program:'
while flag:
    message2 = input(prompt)
    if message2.lower() != 'q':
        with open(file_name5, 'a') as file_object:
            file_object.write(message2 + '\n')
    else:
       flag = False

10.3 异常

10.3.1 处理ZeroDivisionError异常
print(5/0) #ZeroDivisionError: division by zero 不能用数除以0
在这种情况下,python将停止运行程序,并指出引发了哪种异常,而我们可以根据这些信息对程序进行修改。告诉python,发生这种错误的时候,怎么办。

10.3.2 使用 try-except代码块

try:#将导致错误的代码行放在一个try代码块中。若无错误,则跳过except代码块。若try中的语句出错,则运行except中的代码
    print(5/0)
except ZeroDivisionError:
    print("You can't divide by zero!")

10.3.3 使用异常避免崩溃

print("Give me two numbers, and I'll divide them")
print("Enter 'q' to quit")
flag3 = True
while flag3:
    first_number = input('First number:')
    if first_number == 'q':
        break
    second_number = input('Second number')
    if second_number == 'q':
        break
    try:#可能引发异常的代码放在try中
        print(float(first_number) / float((second_number)))
    except ZeroDivisionError:
        print("Errors occur,stop")

10.3.4 处理FileNotFoundError异常

找不到文件也可用try-except处理
file_name6 = 'alict.txt'
try:
    with open(file_name6) as file_object:
        content6 = file_object.read()
except FileNotFoundError:
    print(f"{file_name6} not Found!")

10.3.5 分析文本

title = 'Alice in wonderland'
print(title.split())#split()方法以空格为分隔符将字符串拆成多个部分,并将这些部分都存储到一个列表中

file_name7 = '..\\otherFiles\\chapter_10\\alice.txt'
try:
    with open(file_name7, encoding='utf-8') as file_object:
        content7 = file_object.read()
except FileNotFoundError:
    print(f"Sorry file Not Found")
else:#一些仅在try代码块成功执行时才需要运行的代码,这些代码放在else代码块中
    lists = content7.split()
    nums = len(lists)
    print(f"The file has about {nums} words.")

10.3.6 使用多个文件

def count_words(filename):
    try:
        with open(filename, encoding ='utf-8') as file_object:
            content8 = file_object.read()
    except FileNotFoundError:
        print("Sorry file not Found")
    else:
        lists = content8.split()
        num = len(lists)
        print(f"{filename} has about {num} words.")
# filename = '..\\otherFiles\\chapter_10\\alice.txt'
# count_words(filename)
filelists = ['..\\otherFiles\\chapter_10\\alice.txt',
             '..\\otherFiles\\chapter_10\\moby_dick.txt',
             '..\\otherFiles\\chapter_10\\little_women.txt',
             '..\\otherFiles\\chapter_10\\abs.txt']
for filelist in filelists:
    count_words(filelist)

10.3.7 静默失败

并非每次捕捉到异常都需要告诉用户。有时你希望程序在发生异常时保持静默,就像没有发生一样继续运行
def count2_words(filename):
    try:
        with open(filename, encoding='utf-8') as file_object:
            content8 = file_object.read()
    except FileNotFoundError:
        pass#错误发生时,不会有traceback,也不会有任何输出
    #pass语句还充当了占位符,提醒你这个地方什么都没做,并且以后也许要在这做些什么
    else:
        lists = content8.split()
        num = len(lists)
        print(f"{filename} has about {num} words.")
for filelist in filelists:
    count2_words(filelist)

10.4 存储数据

模块json(JavaScript Object Notion).JavaScript对象符号。它是一种轻量级的数据交换格式,用于存储和交换数据。它是一种独立于语言的格式,非常容易理解,因为它本质上是自描述的。 python中有一个内置包,它支持JSON数据,称为json。

import json
numbers = [2,3,9,8,6,7]
filename8 = 'numbers.json'
with open(filename8,'w') as f:
    json.dump(numbers,f)#json.dump()接受两个实参,要存储的数据、 用于存储数据的文件对象

with open(filename8) as f:
    number = json.load(f)#json.load()加载存储在json文件中的信息,并将其赋给变量。然后打印
print(number)

prompt = "Please input your name?"
prompt += "Otherwise enter 'q' to stop this program:"
active = True
filename9 = 'names.json'
while active:
    uname = input(prompt)
    if uname.lower() == 'q':
        break
    else:
        with open(filename9,'w') as f:
            json.dump(uname,f)

with open(filename9) as f:
    users3 = json.load(f)
print(users3)
#只能w模式下读写。如果是a附加模式,即文件中有好几个用户名,就会报错


10.4.3 重构

在代码正常运行的情况下,将其划分为一系列完成具体工作的函数,称为“重构”。重构使代码更清晰,更易于理解,更容易扩展
def greet_user():
    filename10 = 'username.json'
    try:
        with open(filename10) as f:
            username = json.load(f)
    except FileNotFoundError:
        username = input(prompt)
        with open(filename10,'w') as f:
            json.dump(username,f)
            print(f"I'll remember you when you come back, {username}")
    else:
        print(f"Welcome back, {username}")
greet_user()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值