python 文件和异常

1,从文件中读取数据

要使用文本文件中的信息,首先需要将信息读取到内存中。为此,你可以一次性读取文件的全部内容,也可以以每次一行的方式逐步读取。

1.1 读取整个文件

open()接受文件参数,打开文件。关键字with 在不再需要访问文件后将其关闭。

1.2 逐行提取

使用for循环逐行提取文件内容。rstrip()可以去掉print()多输出的换行

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

open()读取的文件,只能在关键字with代码块中使用,如果想在外使用,可以将数据存储到一个列表中。方法readlines()从文件中读取每一行。

1.4 使用文件的内容

将文件读取到内存中后,就可以以任何方式使用这些数据了。

2,写入文件

保存数据的最简单的方式之一是将其写入到文件中。通过将输出写入文件,即便关闭包含程序输出的终端窗口,这些输出也依然存在:你可以在程序结束运行后查看这些输出,可与别人分享输出文件,还可编写程序来将这些输出读取到内存中并进行处理。

2.1 写入空文件

要将文本写入文件,你在调用open() 时需要提供另一个实参。打开文件时,可指定读取模式('r')、写入模式('w')、附加模式('a')或让你能够读取和写入文件的模式('r+')。如果你省略了模式实参,Python将以默认的只读模式打开文件。
如果你要写入的文件不存在,函数open()将自动创建它。然而,以写入('w')模式打开文件时千万要小心,因为如果指定的文件已经存在,Python将在返回文件对象前清空该文件。

2.2 写入多行

2.3 附加内容到文件

不覆盖原有,在文件中添加内容到末尾

3,异常

Python使用被称为异常 的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继续运行。如果你未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。
异常是使用try-except代码块处理的。try-except代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办。使用了try-except代码块时,即便出现异常,程序也将继续运行,显示你编写的友好的错误消息,而不是令用户迷惑的traceback。

3.1 处理ZeroDivisionError异常

除数为0错误

3.2 使用try-except代码块

我们将导致错误的代码行print(5/0)放在了一个try代码块中。如果try代码块中的代码运行起来没有问题,Python将跳过except代码块。如果try代码块中的代码导致了错误,Python将查找这样的except代码块,并运行其中的代码,即其中指定的错误与引发的错误相同。

3.3 使用异常避免崩溃

发生错误时,如果程序还有工作没有完成,妥善地处理错误就尤其重要。这种情况经常会出现在要求用户提供输入的程序中。如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入,而不至于崩溃。程序崩溃看到的traceback会让不懂技术的用户糊涂,而且如果用户怀有恶意,他会通过traceback获悉你不希望他知道的信息。例如,他将知道你程序文件的名称,还将看到部分不能正确运行的代码。有时候,训练有素的攻击者可根据这些信息判断出可对你的代码发起什么样的攻击。

3.4 else代码块

依赖于try代码块成功执行的代码都放在else代码块中。在这个示例中,如果除法运算成功,我们就使用else代码块来打印结果。
try-except-else代码块的工作原理大致如下:Python尝试执行try代码块中的代码,只有可能引发异常的代码才需要放在try语句中。有时候,有一些仅在try代码块成功执行时才需要运行的代码。这些代码应放在else代码块中。except代码块告诉Python,如果它尝试运行try代码块中的代码时引发了指定的异常,该怎么办。通过预测可能发生错误的代码,可编写健壮的程序,它们即便面临无效数据或缺少资源,也能继续运行,从而能够抵御无意的用户错误和恶意的攻击。

3.5 处理FileNotFoundError异常

使用文件时,一种常见的问题是找不到文件:你要查找的文件可能在其他地方、文件名可能不正确或者这个文件根本就不存在。
在这个示例中,这个错误是函数open()导致的,因此要处理这个错误,必须将try语句放在包含open()的代码行之前:

3.6 分析文本

方法split()以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。结果是一个包含字符串中所有单词的列表,虽然有些单词可能包含标点。为计算
temp.txt包含多少个单词,我们将对文件调用split() ,再计算得到的列表包含多少个元素,从而确定文件大致包含多少个单词:

3.7 使用多个文件

这样做之前,我们先将这个程序的大部分代码移到一个名为count_words()的函数中,这样对多文件进行分析时将更容易:
虽然中间有不存在的文件,但是不影响后面的代码运行。

3.8 出错时一声不吭

pass语句还充当了占位符,它提醒你在程序的某个地方什么都没有做,并且以后也许要在这里做些什么。

4,存储数据

很多程序都要求用户输入某种信息,如让用户存储游戏首选项或提供要可视化的数据。不管专注的是什么,程序都把用户提供的信息存储在列表和字典等数据结构中。用户关闭程序时,你几乎总是要保存他们提供的信息,一种简单的方式是使用模块json来存储数据。

4.1 使用json.dump()和json.load()

我们来编写一个存储一组数字的简短程序,再编写一个将这些数字读取到内存中的程序。第一个程序将使用json.dump()来存储这组数字,而第二个程序将使用json.load()。
函数json.dump()接受两个实参:要存储的数据以及可用于存储数据的文件对象。下面演示了如何使用json.dump()来存储数字列表:


使用json.load()将这个列表读取到内存中。

4.2 保存和读取用户生成的数据

对于用户生成的数据,使用json 保存它们大有裨益,因为如果不以某种方式进行存储,等程序停止运行时用户的信息将丢失。下面来看一个这样的例子:用户首次运行程序时被提示输入自己的名字,这样再次运行程序时就记住他了。
我们先来存储用户的名字:

现在再编写一个程序,向其名字被存储的用户发出问候:

我们需要将这两个程序合并到一个程序中。这个程序运行时,我们将尝试从文件username.json中获取用户名,因此我们首先编写一个尝试恢复用户名的try代码块。如果这个文件不存在,我们就在except代码块中提示用户输入用户名,并将其存储在username.json中,以便程序再次运行时能够获取它:

4.3 重构

你经常会遇到这样的情况:代码能够正确地运行,但可做进一步的改进——将代码划分为一系列完成具体工作的函数。这样的过程被称为重构。重构让代码更清晰、更易于理解、更容易扩展。
因此我们将问候用户所有代码都放到一个名为greet_user()的函数中。

下面来重构greet_user(),让它不执行这么多任务。为此,我们首先将获取存储的用户名的代码移到另一个函数中。

我们再将greet_user()中的另一个代码块提取出来,将没有存储用户名时提示用户输入的代码放在一个独立的函数中:

要编写出清晰而易于维护和扩展的代码,这种划分工作必不可少。

posted @ 2021-06-13 11:29  小白运维狗  阅读(120)  评论(0)    收藏  举报