Python入门 - 第10章 文件和异常

此系列文章的创作初衷是作为读书过程中的笔记,而非教程类文章。

第10章 文件和异常

10.1 从文件中读取数据

读取整个文件

  • 下面是一个读取文件的示例:
filePath = "test.txt"
with open(filePath) as file:
    contents = file.read()
    print(contents)
  1. 通过open函数打开文件。open函数接收文件的路径(可以使用绝对路径或相对路径),并返回一个文件对象。此处open()返回一个文本文件。
  2. 此示例使用了with关键字来打开文件,with语句可以在文件访问接收后自动将文件关闭,类似于Java中的try-with-resources语句。也可以使用opne()和close()完成打开和关闭文件的任务,但不推荐这么做——一是因为可能忘记调用close();二是因为如果程序出现bug导致close()未调用,则文件将不会关闭。
  3. read()函数会一次性读取文件的全部内容。如果文件末尾有换行符,则read函数会将换行符也一并读入,在输出时将多显示一个换行(注意print()函数也会换行)。若要去除多余的换行符,可以使用rstrip()方法。
  4. Python以字符串的形式读取文件内容。如果希望知道文件中是否包含特定的内容,可以使用in关键字:
filePath = "test.txt"
keyword = "some word"
with open(filePath) as file:
    contents = file.read()
if keyword in contents:
    # do something
    pass # 为保证语法正确使用的占位关键字,不会做任何事情
  1. 要将文件中的某部分内容全部替换为另一部分内容(例如,要将一个单词全部替换为另一个单词),可以使用replace()方法:
filePath = "test.txt"
src = "wordA"
target = "wordB"
with open(filePath) as file:
    contents = file.read()
    contents = contents.replace(src, target) # replace()方法不会修改原字符串,应将方法返回的结果赋给变量来实现修改
    print(contents)

文件路径

  • 在Windows中,使用反斜杠分隔文件目录。由于反斜杠同时是转义字符,应用双反斜杠表示反斜杠;或者,也可以在字符串开头加上一个“r”表示使用原始字符串,这样python就不会试图将反斜杠解释为转义字符。
open(r"C:\Users\Administrator\Documents\test.txt")
  • 推荐将程序需要使用的文件置于程序文件所在的目录或子目录下,并使用相对路径。这样即使程序迁移,也能保证路径正确。

逐行读取

  • 对文本文件对象使用for语句,可以逐行读取文件内容:
filePath = "test.txt"

with open(filePath) as file:
    for line in file:
        print(line.strip())

由于文件内容的每一行末尾都存在换行符,此处用strip()方法将之去除。

10.2 写入文件

  • 下面是一段打开并写入文件的样例代码:
with open("test.txt", "w+") as file:
    file.write("I like Python.\n")
    file.write("But I like Java more.\n")
    file.write(str(1))
  1. open()的第二个实参表示打开文件的方式,常用的方式有以下几种:
    1. “r”:只读模式,默认的模式。文件不存在时抛出FileNotFoundError。
    2. “w”:写入模式(只写)。当文件不存在时会新建文件,当文件已存在时将清空原文件的内容
    3. “a”:追加模式(只写)。当文件不存在时会新建文件;当文件已存在时,将指针移至文件末尾,从此处开始追加内容。
    4. “r+”:读写模式。文件存在时,将指针置于文件开头,允许读写;文件不存在时抛出FileNotFoundError。
    5. “w+”:读写模式。当文件不存在时会新建文件,当文件已存在时将清空原文件的内容
    6. “a+”:读写模式。当文件不存在时会新建文件;当文件已存在时,将指针移至文件末尾,允许读写。
    7. 此外,还有"rb","rb+"等模式,这些模式用于以二进制方式进行读写,不在本教材的讨论范围内,此处略去。
  2. write()函数可用于向文件写入字符串。write()不会自动追加换行符,需要注意手动追加。此外,write()只用于写入字符串,如果要写入数字,需要用str()将其转为字符串。

10.3 异常

  • Python使用称为异常的对象来管理程序执行期间发生的错误。如果编写了处理异常的代码,程序将在处理异常后继续运行;否则,程序将终止,并显示一个traceback,其中包含了有关异常信息的报告。

try-except-else

  • Python使用try-except结构处理异常,在希望遇到异常时进行更多操作时,还可能用到try-except-finally或try-except-else,甚至try-except-else-finally结构。使用try-except处理异常,有助于让程序更健壮,同时也有助于提升用户体验:用户能明确地知道程序出现了何种一场,而无需面对令人迷惑的traceback。使用try-except的额外好处在于,它可以避免恶意用户借助traceback获悉你的文件名或是出错的部分代码,这将有助于避免代码遭受攻击。
  • 下面是一段try-except-else的样例代码:
def main(a: int, b: int) -> None:
    try:
        ans = a / b
    except ZeroDivisionError:
        print("不能将0作为除数。")
    except IndexError:
        pass
    else:
        print(ans)
    print("After Try")
  1. Python首先执行try块中的代码。只有可能引起异常的代码才应放在try块中。在本例中,ans = a / b是可能引起异常的代码,当b为0时,将抛出ZeroDivisionError。
  2. except告诉Python在发生指定的异常时应如何处理。上述的ans = a / b语句抛出异常后,Python将在except列表中逐个寻找异常类型是否匹配,如果找到匹配的语句块就执行语句块,然后执行try-except-else结构后的print()语句;如果未能找到匹配的except块,将导致程序终止。无论是否找到匹配的except语句,都将跳过else语句块。
  3. 只有在try中的语句未导致异常时,else语句块中的语句才会执行。
  4. 有时候,希望程序在捕获异常时什么也不做,这时可以在except块中写pass。pass是一个占位语句,当Python遇到pass时,什么也不会做。同时,pass还避免了块中没有语句导致的语法错误。上面try块中的代码不会抛出IndexError,只是为了展示pass的作用而写的。
  5. finally语句块置于try,except和else之后,用于放置需要确保执行的语句。即使在try块中抛出的异常没有被捕获,或者try/except/else语句中使用了return,也会确保进入finally语句块。finally不在教材的讨论范围内,不再详细讨论。

with-as语句与异常

  • with-as语句本质上启动了所谓“上下文管理器”协议,该协议本质上是一个try-finally结构。例如下面的代码:
with open("test.txt") as file:
    pass # 占位语句,什么都不会做

可以理解为下面的代码(但并不等效):

try:
    file = open("test.txt")
    pass
finally:
    file.close()

因此,即使with-as块中出现了异常,或者使用了return,仍然能够确保文件被关闭。

split(delimiter: str) -> list

  • split()函数以delimiter为界,将字符串分割为多个子串,并置于一个列表中。当不传入任何参数时,分隔符为空格。
    • 注意:split(delimiter: str) -> list并不是split()函数的签名,只是为了方便说明才这样写的。

10.4 存储数据

  • 可以使用json存储数据。存储和读取数据依赖json.dump()和json.load()函数。
  • json.dump()的简化版原型如下:
dump(obj: any, fp: IO[str]) -> None

obj是需要向文件写入的对象,可以是整型、浮点、字符串、列表、字典等,fp是用于写入的文件对象。对于上面提及的五种类型,json存储的形式与print()输出的形式完全相同(除了单引号’在json中表示为双引号")。

  • json.load()接受文件对象作为参数。函数读取json文件,并将内容作为对象返回。例如,一个json文件中存储了如下内容:
[1, 2, 3]

json.load()会将内容识别为列表并返回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值