python文件的操作和异常之异常

简介: python文件的操作和异常之异常

异常:

python使用称为异常的特殊类对象来管理程序执行期间发生的错误,每当发生让python不知所措的错误时,他都会创建一个异常的对象。


如果你编写了处理该异常的代码,程序将继续进行,如果未对异常进行处理,程序将停止并显示traceback,其中包含有关异常的报告。


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

处理ZeroDivisionErro:

举例:

我们早已在数学中学过,0不能在分母的位置,但还是让python执行如下程序:

print(5/0)

输出结果产生了traceback:

Traceback (most recent call last):
  File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 14, in <module>
    print(5/0)
ZeroDivisionError: division by zero

在上述 traceback中,指出的错误 ZeroDivisionError 是个异常对象。Python 无法按你的要求做时,就会创建这种对象。在这种情况下,**Python 将停止运行程序,并指出引发了哪种异常,**而我们可根据这些信息对程序进行修改。下面来告诉 Python,发生这种错误时怎么办。这样,如果再次发生此类错误,我们就有备无患了。


使用try-except代码块:

当你认为可能发生错误时,可编写一个代码块try-except代码块来处理可能引发的异常,你让python尝试运行一些代码,并告诉它如果这些代码引发了指定的异常该怎么办。

处理ZeroDivisionErro异常的try-except代码块类似于下面这样:

try:
    print(5/0)
except ZeroDivisionError:
    print("you can't divide by zero")

将导致错误的代码行print(5/0)放在一个try代码块中,如果try代码块中的代码运行起来没有问题,python将跳过execpt代码块,如果try代码块中的代码导致了错误,python将查找与之匹配的except代码块并运行其中的代码。

you can't divide by zero

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

使用异常避免崩溃:

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

举例:

该程序是实现求两个数的商

print("Give me two numbers,and I'll divide them.")
print("enter 'q' to quit")
while True:
    fist_number=input("\nfist number:")
    if fist_number=='q':
        break
    second_number=input("\nsecond number:")
    if second_number=='q':
        break
    answer=int(fist_number)/int(second_number)
    print(answer)

由于对被除数为0的这种情况未作任何处理,所以当被除数为0时,会出现异常

Give me two numbers,and I'll divide them.
enter 'q' to quit
fist number:19
second number:0
Traceback (most recent call last):
  File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 24, in <module>
    answer=int(fist_number)/int(second_number)
ZeroDivisionError: division by zero

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

那么应该怎么妥善解决这个问题呢?

答案是:使用try-except代码块,那么具体怎么操作呢?


else代码块:

通过将可能引发错误的代码块放入try-except代码块中,可提高程序抵御错误的能力。

举例:

while True:
    fist_number=input("\nfist number:")
    if fist_number=='q':
        break
    second_number=input("\nsecond number:")
    if second_number=='q':
        break
    try:
        answer=int(fist_number)/int(second_number)#可能引发程序崩溃的代码
    except ZeroDivisionError:
        print("you can't divide by 0!")#try语句后程序未成功运行,友情提示错误的消息内容
    else:
        print(answer)#try语句后程序成功运行的代码
Give me two numbers,and I'll divide them.
enter 'q' to quit
fist number:12
second number:0#当被除数是0
you can't divide by 0!#会输出良好的友情提醒而不是程序崩溃

try-except-else代码块的工作原理大致如下:

python尝试执行try代码块中的代码,只有可能引发错误的代码才需要放在try语句中,有时候,有一些仅在try代码块成功执行时才需要运行的代码,这些代码应放在else代码块中,except代码块告诉python,如果尝试运行try代码块时引发了指定的异常该怎么办。


处理FileNotFoundError异常:

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

举例:

下面我们通过读取系统不存在的文件:

with open("789.txt",encoding='utf-8') as f:
    f.read()

python无法读取不存在的文件,因此它将引发异常:

Traceback (most recent call last):
  File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 30, in <module>
    with open("789.txt",encoding='utf-8') as f:
FileNotFoundError: [Errno 2] No such file or directory: '789.txt'

上述中的Traceback的最后一行报告了FileNotFoundError异常,这是python找不到要打开的文件时创建的异常,在本例中,是由open函数导致的,因此,要处理这个错误,必须将try语句放在包含open()的代码行之前:


优化之后的代码:

try:
    filename='789.txt'
    with open("filename",encoding='utf-8') as f:
        f.read()
except FileNotFoundError:
    print(f"sorry,the file{filename}does not exist")

如下图所示,当文件不存在时,python此时并没有引发异常,而是输出一条提示的信息。

sorry,the file789.txtdoes not exist

如果文件不存在,这个程序就什么也做不了,错误处理代码的意义不大。

当我们需要处理多个文件的时候,异常处理可提供的帮助:

分析文本:

你可以分析包含整本书的文本文件。

举例:

filename="123.txt"
try:
    with open(filename,encoding="utf-8") as f:
        contents=f.read()#运行成功,执行else代码块后面的语句
except FileNotFoundError:
    print(f"sorry,the file{filename} does not exist")
else:
    words=contents.split()#以空格作为标记符号,将字符串分隔开
    num_words=len(words)#计算字符串的长度
    print(f"the file {filename} has about {num_words} words")
the file 123.txt has about 98 words

123.txt内容如下:

Currently,there is a widespread concern over (the issue that)__作文题目 .
It is really an important concern to every one of us. As a result,we must spare no efforts to take some measures to
solve this problem.As we know that there are many steps which can be taken to undo this problem. First of all,__途径一
_In addition, another way contributing to successfully solving the problem is 途径二Above all, to solve the problem of
 ___作文题目,we should find a number of various ways. But as far as I am concerned, I would prefer to solve the problem
 in this way,that is to say, 方法

使用多个文件:

下面同时多分析几本书:

在此之前我们先将这个程序的代码移到一个名为count_words的函数中,这样,对多本书的分析就会更加方便。

def count_words(filename):#计算一个文件里面大致包含多少词
    try:
     with open(filename,encoding="utf-8") as f:
            contents=f.read()
    except FileNotFoundError:
        print(f"sorry,the file{filename} does not exist")
    else:
        words=contents.split()
        num_words=len(words)
        print(f"the file {filename} has about {num_words} words")
fliename=["123.txt","456.py"]#将多个文本存储在一个列表中
for filename in fliename:#使用for循环对其进行遍历
    count_words(filename)#依次调用函数对不同文本的词进行统计
the file 123.txt has about 14 words
the file 456.py has about 42 words

如果其中的某个文件不存在呢?

使用try-except代码块的效果:

def count_words(filename):#计算一个文件里面大致包含多少词
    try:
     with open(filename,encoding="utf-8") as f:
            contents=f.read()
    except FileNotFoundError:
        print(f"sorry,the file{filename} does not exist")
    else:
        words=contents.split()
        num_words=len(words)
        print(f"the file {filename} has about {num_words} words")
fliename=["123.txt","789.py","456.py"]#将多个文本存储在一个列表中
for filename in fliename:#使用for循环对其进行遍历
    count_words(filename)#依次调用函数对不同文本的词进行统计
the file 123.txt has about 14 words
sorry,the file789.py does not exist
the file 456.py has about 42 words

不使用try-except代码块的效果:

def count_words(filename):#计算一个文件里面大致包含多少词
    # try:
     with open(filename,encoding="utf-8") as f:
            contents=f.read()
            words=contents.split()
            num_words=len(words)
            print(f"the file {filename} has about {num_words} words")
fliename=["123.txt","789.py","456.py"]
for filename in fliename:
    count_words(filename)
the file 123.txt has about 14 words
Traceback (most recent call last):
  File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 41, in <module>
    count_words(filename)
  File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 32, in count_words
    with open(filename,encoding="utf-8") as f:
FileNotFoundError: [Errno 2] No such file or directory: '789.py'

通过对比上述两个的执行效果,我们发现使用try_except代码块,在某文件不存在的情况下,编译器不仅不会发生异常,而且不存在文件后面的文件依然会被编译器进行分析,而不使用try-except代码块,在某文件不存在的情况下,traceback不仅被完整显示,而且后面的文本编译器不会进行分析。

这样对比,是不是觉得使用try——except代码块更友好一些?

静默失败:

在上面的示例中,我们告诉用户有一个文件找不到,但并非每次产生异常都要告诉用户,有时候你希望程序在发生异常时保持静默,就像什么都没有发生一样继续运行,要让程序静默失败,可像通常编写try代码块那样,但在except代码块中明确告诉python什么都不要做,python有一个pass语句,可让python在代码块中什么都不要做。


举例:

def count_words(filename):#计算一个文件里面大致包含多少词
    try:
     with open(filename,encoding="utf-8") as f:
            contents=f.read()
    except FileNotFoundError:
       pass#当出现异常时,python将不会告诉用户任何东西
    else:
        words=contents.split()
        num_words=len(words)
        print(f"the file {filename} has about {num_words} words")
fliename=["123.txt","789.py","456.py"]#将多个文本存储在一个列表中
for filename in fliename:#使用for循环对其进行遍历
    count_words(filename)#依次调用函数对不同文本的词进行统计

相比于前面的程序,这个程序唯一不同的地方就是在except代码块后面使用的是pass语句,现在,当

出现FileNotFoundError异常时,将执行except代码块中的代码,但什么都不会输出,这种错误发生时,不会出现traceback,也没有任何输出语句,用户将看到存在的文件输出的内容,但不会看到有文件没有被找到的内容。

the file 123.txt has about 14 words
the file 456.py has about 42 words

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

决定报告哪些错误

该在什么情况下向用户报告错误?

如果用户知道要分析哪些文件,他们可能希望在有文件却没有分析时出现一条消息来告知原因。

该在什么情况下静默失败呢?

如果用户只想看到结果,并不知道要分析那些文件,可能就无须在有些文件不存在时告知他们。向用户显示他不想看到的信息可能会降低程序的可用性。Python 的错误处理结构让你能够细致地控制与用户分享错误信息,要分享多少信息由你决定。


编写得很好且经过详尽测试的代码不容易出现内部错误,如语法或逻辑错误,但只要程序依
赖于外部因素,如用户输人、存在指定的文件、有网络链接,就有可能出现异常
。凭借经验可判

该在程序的什么地方包含异常处理块。以及出现错误时,该向用户提供多少相关的信息。

相关文章
|
1月前
|
自然语言处理 数据处理 Python
python操作和解析ppt文件 | python小知识
本文将带你从零开始,了解PPT解析的工具、工作原理以及常用的基本操作,并提供具体的代码示例和必要的说明【10月更文挑战第4天】
305 60
|
24天前
|
存储 索引 Python
|
29天前
|
安全 Linux 数据安全/隐私保护
python知识点100篇系列(15)-加密python源代码为pyd文件
【10月更文挑战第5天】为了保护Python源码不被查看,可将其编译成二进制文件(Windows下为.pyd,Linux下为.so)。以Python3.8为例,通过Cython工具,先写好Python代码并加入`# cython: language_level=3`指令,安装easycython库后,使用`easycython *.py`命令编译源文件,最终生成.pyd文件供直接导入使用。
python知识点100篇系列(15)-加密python源代码为pyd文件
|
12天前
|
开发者 Python
Python中__init__.py文件的作用
`__init__.py`文件在Python包管理中扮演着重要角色,通过标识目录为包、初始化包、控制导入行为、支持递归包结构以及定义包的命名空间,`__init__.py`文件为组织和管理Python代码提供了强大支持。理解并正确使用 `__init__.py`文件,可以帮助开发者更好地组织代码,提高代码的可维护性和可读性。
15 2
|
1月前
|
Linux 区块链 Python
Python实用记录(十三):python脚本打包exe文件并运行
这篇文章介绍了如何使用PyInstaller将Python脚本打包成可执行文件(exe),并提供了详细的步骤和注意事项。
51 1
Python实用记录(十三):python脚本打包exe文件并运行
|
25天前
|
Python
Python生成器、装饰器、异常
【10月更文挑战第15天】
|
28天前
|
Java Python
> python知识点100篇系列(19)-使用python下载文件的几种方式
【10月更文挑战第7天】本文介绍了使用Python下载文件的五种方法,包括使用requests、wget、线程池、urllib3和asyncio模块。每种方法适用于不同的场景,如单文件下载、多文件并发下载等,提供了丰富的选择。
|
28天前
|
数据安全/隐私保护 流计算 开发者
python知识点100篇系列(18)-解析m3u8文件的下载视频
【10月更文挑战第6天】m3u8是苹果公司推出的一种视频播放标准,采用UTF-8编码,主要用于记录视频的网络地址。HLS(Http Live Streaming)是苹果公司提出的一种基于HTTP的流媒体传输协议,通过m3u8索引文件按序访问ts文件,实现音视频播放。本文介绍了如何通过浏览器找到m3u8文件,解析m3u8文件获取ts文件地址,下载ts文件并解密(如有必要),最后使用ffmpeg合并ts文件为mp4文件。
|
1月前
|
JSON 数据格式 Python
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
这篇文章介绍了一个Python脚本,用于统计TXT或JSON文件中特定单词的出现次数。它包含两个函数,分别处理文本和JSON文件,并通过命令行参数接收文件路径、目标单词和文件格式。文章还提供了代码逻辑的解释和示例用法。
41 0
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
|
1月前
|
Python
Python实用记录(十二):文件夹下所有文件重命名以及根据图片路径保存到新路径下保存
这篇文章介绍了如何使用Python脚本对TTK100_VOC数据集中的JPEGImages文件夹下的图片文件进行批量重命名,并将它们保存到指定的新路径。
32 0