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 的错误处理结构让你能够细致地控制与用户分享错误信息,要分享多少信息由你决定。


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

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

相关文章
|
7天前
|
计算机视觉 Python
如何使用Python将TS文件转换为MP4
本文介绍了如何使用Python和FFmpeg将TS文件转换为MP4文件。首先需要安装Python和FFmpeg,然后通过`subprocess`模块调用FFmpeg命令,实现文件格式的转换。代码示例展示了具体的操作步骤,包括检查文件存在性、构建FFmpeg命令和执行转换过程。
30 7
|
1月前
|
测试技术 开发者 Python
对于Python中的异常要如何处理,raise关键字你真的了解吗?一篇文章带你从头了解
`raise`关键字在Python中用于显式引发异常,允许开发者在检测到错误条件时中断程序流程,并通过异常处理机制(如try-except块)接管控制。`raise`后可跟异常类型、异常对象及错误信息,适用于验证输入、处理错误、自定义异常、重新引发异常及测试等场景。例如,`raise ValueError(&quot;Invalid input&quot;)`用于验证输入数据,若不符合预期则引发异常,确保数据准确并提供清晰错误信息。此外,通过自定义异常类,可以针对特定错误情况提供更具体的信息,增强代码的健壮性和可维护性。
|
1月前
|
Python
在Python中,`try...except`语句用于捕获和处理程序运行时的异常
在Python中,`try...except`语句用于捕获和处理程序运行时的异常
44 5
|
1月前
|
Python
在Python中,自定义函数可以抛出自定义异常
在Python中,自定义函数可以抛出自定义异常
44 5
|
1月前
|
存储 开发者 Python
自定义Python的异常
自定义Python的异常
17 5
|
2月前
|
存储 索引 Python
|
2月前
|
安全 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文件
|
1月前
|
开发者 Python
Python中__init__.py文件的作用
`__init__.py`文件在Python包管理中扮演着重要角色,通过标识目录为包、初始化包、控制导入行为、支持递归包结构以及定义包的命名空间,`__init__.py`文件为组织和管理Python代码提供了强大支持。理解并正确使用 `__init__.py`文件,可以帮助开发者更好地组织代码,提高代码的可维护性和可读性。
45 2
|
1月前
|
中间件 Docker Python
【Azure Function】FTP上传了Python Function文件后,无法在门户页面加载函数的问题
通过FTP上传Python Function至Azure云后,出现函数列表无法加载的问题。经排查,发现是由于`requirements.txt`中的依赖包未被正确安装。解决方法为:在本地安装依赖包到`.python_packages/lib/site-packages`目录,再将该目录内容上传至云上的`wwwroot`目录,并重启应用。最终成功加载函数列表。
|
2月前
|
Python
Python生成器、装饰器、异常
【10月更文挑战第15天】