文件和异常

2022-09-04 22:10:36 浏览数 (1)

你将学习处理文件,让程序能够快速地分析大量的数据,你将学习错误处理,避免程序在面对意外情形时崩溃;特殊对象,用于管理程序运行时出现的错误;

你将学习模json,它让你能够保存用户数据,以避免在程序运行后丢失。学习处理文件和保存数据可让你的程序使用起来更容易:用户将能够选择输入什么样的数据,以及在什么时候输入;

用户使用你的程序做一些工作之后,可将程序关闭,以后再接着往下做。学习处理异常可帮助你应对文件不存在的情形,以及处理其他可能导致程序崩溃的问题。这让你的程序在面对错误的数据时更健壮------不管这些错误数据源自无意的错误,还是源自破坏程序的恶意企图。

从文件中读取数据:

每当需要分析或修改存储在文件中的信息时,读取文件都很有用,对数据分析应用程序来说尤其如此。要使用文本文件中的信息,首先需要将信息读到内存中。为此,你可以一次性读取文件的全部内容,也可以以每次一行的方式逐步读取。你只管打开文件,并在需要时使用它,Python自动会在合适的时候自动将其关闭。Python方法rstrip( )删除(剥除)字符串末尾的空白。

文件路径:

要让Python打开不与程序文件属于同一个目录中的文件,需要提供文件路径它让Python到系统的特定位置去查找。相对文件路径让Python到指定的位置去查找,而该位置是相对于当前运行的程序所在目录的。

在Linux和OS X中,你可以这样编写代码:with open('text.files/filename.txt') as file_object;

你还可以将文件在计算机中的准确位置告诉Python,这样就不用关心当前运行的程序存储在什么地方了。这种称为绝对文件路径。在相对路径行不通时,可使用绝对路径。通过使用绝对路径,可读取系统任何地方的文件,就目前而言,最简单的做法是,要么将数据文件存储在程序文件所在的目录,要么将其存储在程序文件所造目录下的一个文件夹中。

注意:windows系统有时能够正确地解读文件路径中的斜杠。如果你使用的是Windows系统,且结果不符合预期,请确保在文件路径中使用的是反斜杠。另外,由于反斜杠在Python中被视为转义标记,为在Windows中确保万无一失,应以原始字符串的方式指定路径,即在开头的单引号前加r。

逐行读取:

读取文件时,常常需要检查其中的每一行:你可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。例如:你可能要遍历一个包含天气数据的文件,并使用天气描述中包含字样Sunny的行。在新闻报道中,你可能会查找包含创建一个包含标签<headline>的行,并按特定的格式设置它。

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

使用关键字with时,open( )返回的文件对象只在with代码块中可用。如果要在with代码块外访问文件的内容。可在with内将文件的各行存储在一个列表中,并在with代码块外使用该列表,你可以立即处理文件的各个部分,也可以推迟程序后面再处理。

使用文件的内容:

读取文件时,Python将其中的所有文件都解读为字符串。如果你读取的是数字,并要将其作为数值使用,就必须使用函数int( )将其转换为整数,或使用float( )将其转换为浮点数。对你要处理的数据量,Python没有任何限制;只要系统的内存足够多,你想处理多少数据都可以。

写入文件:

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

写入空文件:

要将文本写入文件,你在调用open( )时需要提供另一个实参,告诉Python你要写入打开的文件。如果你要写入的文件不存在,函数open( )将自动创建它。然而,以写入('w')模式打开文件时千万要小心。因为指定的文件已经存在,Python将在返回文件对象前清空该文件。注意:Python只能将字符串写入文件。要将数值数据存储到文本文件中,必须先使用函数str( )将其转换为字符串格式。

写入多行:

函数write( )不会在你写入文本末尾添加换行符,因此如果你写入多行时没有指定换行符,文件看起来可能是你希望的那样:

附加到文件:

如果你给文件添加内容,而不是覆盖原有的内容,可以附加模式打开文件。你以附加模式打开文件时,Python不会在返回文件对象前清空文件,而你写入到文件的行都将添加到文件末尾。如果你指定的文件不存在,Python将为你创建一个空文件。

异常:

每当发生让Python不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的的代码,程序将继续运行;如果你未对异常进行处理,程序将停止,并显示一个traceback,其中包含着有关异常的报告。

例:处理ZeroDivisionError异常,输入代码:

代码语言:javascript复制
print(5/0)

显然python无法这么做,因此你将看到一个traceback:

代码语言:javascript复制
Traceback(most recent call last):
  File"division.py",line 1, in <module>
    print(5/0)
zeroDivisionError: division by zero

在上述traceback中,zeroDivisionError是一个异常对象。Python无法按你的要求做时,就会创建这种对象。在这种情况下,python将停止运行程序,并指出引发了哪种异常,而我们可根据这些信息对程序进行修改。当你认为可能发生了错误时,可编写一个try-expect代码来处理可能引发的异常。让你python尝试运行一些代码,并告诉它如果这些代码引发了指定的异常,该怎么办。

处理zeroDivisionError异常时try-expect代码块类似于下面这样:

代码语言:javascript复制
try:
    print(5/0)
expect zeroDivisionError:
    print("You can't divide by zero!")

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

在这个示例中,try代码块中的代码引发了zeroDivisonError异常,因此python指出了该如何解决问题的expect代码块,并运行其中的代码。这样,用户看到的是一条友好的错误信息,而不是traceback:

代码语言:javascript复制
You can't divide by zero!

如果try-expect代码块后面还有其他代码,程序将接着运行,因为已经告诉了python如何处理这种错误。

异常是使用try-expext代码块处理的。try-expect代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办。使用了try-expect代码块时,即使出现异常,程序也将继续运行:显示你编写的友好的错误消息,而不是令用户迷惑的traceback。

使用异常避免崩溃

发生错误时,如果程序还有工作没有完成,妥善处理错误就尤其重要。这种情况经常出现在要求用户提供输入的程序中;如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入而不至于崩溃。

代码语言:javascript复制
division.py

print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")

while Ture:
    first_number = input("n First number: ")
    if first_number == 'q':
        break
    second_number = input("Second number: ")
    if first_number == 'q':
        break
    answer = int(first_number) / int(first_number)
    print(answer)

这个程序提示用户输入一个数字,并将其存储到变量first_number中;如果用户输入的不是表示推出的q,就再次提示用户输入一个数字,并将其存储到变量second_number中。接下来计算这两个数字的值。这个程序没有采取任何处理错误的措施,因此让它执行除数为0的出发运算时,它将崩溃:

代码语言:javascript复制
Give me two number, and I'll divide them.
Enter 'q' to quit.

First number: 5
Second number: 0
Traceback(most recent call last):
  File 'division.py', line 9 , 10 <moduel>
     answer = int(first_number) / int(second_number)
ZeroDivisionError: division by zero

程序崩溃可不好,但让用户看到traceback也不是好主意。不懂技术的用户会被它们搞糊涂,而且如果用户怀有恶意,他会通过traceback获悉你不希望他知道的信息。例如,他将知道你的程序文件中的名称,还将看到部分不能正确运行的代码。有时候,训练有素的攻击者可根据这些信息判断出可对你的代码发起什么样的攻击。

使用异常避免崩溃:

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

else代码块:

通过将可能引发错误的代码块放在try-expect代码块中,可提高这个程序抵御错误的能力。错误是执行处罚运算的代码导致的,因此我们需要将它放在try-expect代码中。try-expect-else代码块的工作原理大致如下:Python尝试执行try代码中的代码,只有可能引发异常的代码才放到try语句中。有时候有一些仅在try代码成功执行时才需要运行的代码;这些代码应放在else代码中。expect代码块告诉Python,如果它尝试运行try代码块中的代码时引发了指定的异常该怎么办。通过预测可能发生错误的代码,可编写健壮的程序,它们即便面临无效数据或缺少资源,也能继续运行,从而能够抵御无意的用户错误和恶意攻击。

处理FileNotFoundError异常:

使用文件时,一种常见的问题就是找不到文件:你要查找的文件可能在其他地方,文件名可能不正确或者这个文件根本就不存在。对于所有这些情形,都可以使用try-expect代码块以直观的方式进行处理。

使用多个文件:

在这个实例中,使用try-expect代码提供了两个重要的优点:避免让用户看到traceback;让程序能够继续分析能够找到其他文件。失败时一声不吭:Python有一个pass语句,可在代码块中使用它来让Python生命都不要做。pass语句还充当了占位符,它提醒你在程序的某个地方什么都没有做,并且以后也许要在这里做些什么。

存储数据:

很多程序都要求用户输入某种信息,如让用户存储游戏选项或提供可视化数据。不管专注的是什么,程序都把用户提供的信息存储在列表和字典等数据结构中。用户关闭程序时,你几乎总是要保存他们提供的信息,一种简单的方式是使用模块icon来存储数据。模块json让你能够将简单的Python数据结构转储到文件中,并且程序再次运行时加载该文件中的数据。你还可以使用json在Python程序之间分享数据。更重要的是,json数据格式并非Python专用的,这让你能够将以json格式存储的数据与使用其他编程语言的人分享。这是一种轻便格式,很有用,也易于学习。注意:JSON(JavaScript Object Notation)格式最初是为Java Script 开发的,但随后成了一种常见的格式,被包括Python在内的太多语言采用。

重构:

你经常会遇到这样的情况:代码能够正确地运行,但可做进一步的改进------将代码划分为一系列完成具体工作的函数。这样的过程被称为重构。重构让代码更清晰,更易于理解,更容易扩展。

0 人点赞