专栏首页python3Python 错误处理

Python 错误处理

1.1 错误处理

1.1.1 try

>>> try:

...    print('try...')

...    r = 10 / 0

...    print('result:', r)

... except ZeroDivisionError as e:

...    print('except:', e)

... finally:

...    print('finally...')

...    print('END')

...

try...

except: division by zero

finally...

END

当我们认为某些代码可能会出错时,就可以用try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,如果有finally语句块,则执行finally语句块,至此,执行完毕。

finally语句块无论是否执行except,都会被执行的。

同时定义多个except

>>> try:

...    print('try...')

...    r = 10 / int('a')

...    print('result:', r)

... except ValueError as e:    --异常1

...    print('ValueError:', e)

... except ZeroDivisionError as e:   --异常2

...    print('except:', e)

... else:   --无异常时执行else

...    print('no error')

... finally:

...    print('finally...')

...    print('END')

...

try...

ValueError: invalid literal for int() withbase 10: 'a'

finally...

END

跨越多层调用

使用try...except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用foo(),foo()调用bar(),结果bar()出错了,这时,只要main()捕获到了,就可以处理。

>>> def foo(s):

...    return 10 / int(s)

...

>>> def bar(s):

...    return foo(s) *2

...

>>> def main():

...    try:

...        bar('0')

...    except Exception as e:

...        print('Error:', e)

...    finally:

...        print('finally...')

...

>>> main()

Error: division by zero

finally...

只要在合适的层次去捕获错误就可以了。

1.1.2 调用堆栈

[root@daidai python]# cat err.py

#!/bin/bash/python

# -*- coding:utf-8 -*-

def foo(s):

   return 10 / int(s)

def bar(s):

   return foo(s) * 2

def main():

   bar('0')

main()

[root@daidai python]# python err.py

Traceback (most recent call last):

 File "err.py", line 13, in <module>

   main()

 File "err.py", line 11, in main

   bar('0')

 File "err.py", line 8, in bar

   return foo(s) * 2

 File "err.py", line 5, in foo

   return 10 / int(s)

ZeroDivisionError: division by zero    --最后便是错误的根源

1.1.3 记录错误

捕捉错误,把错误堆栈记录,让程序继续运行。

Python内置的logging模块可以非常容易地记录错误信息。

[root@daidai python]# cat err_logging.py

#!/usr/bin/python

# -*- coding:utf-8 -*-

import logging

def foo(s):

   return 10 / int(s)

def bar(s):

   return foo(s) * 2

def main():

   try:

       bar('0')

   except Exception as e:

logging.exception(e)

main()

print('END')

[root@daidai python]# python err_logging.py

ERROR:root:division by zero

Traceback (most recent call last):

 File "err_logging.py", line 14, in main

    bar('0')

 File "err_logging.py", line 10, in bar

   return foo(s) * 2

 File "err_logging.py", line 7, in foo

   return 10 / int(s)

ZeroDivisionError: division by zero

END

1.1.4 抛出错误

尽量使用python内置的错误类型。

错误是class,捕获一个错误就是捕获到该class的一个实例。

定义一个错误class,选择好继承关系。

>>> class FooError(ValueError):

...    pass

...

>>> def foo(s):

...    n = int(s)

...    if n == 0:

...         raise FooError('invalid value: %s' % s)

...    return 10 / n

...

>>> foo('0')

Traceback (most recent call last):

 File "<stdin>", line 1, in <module>

 File "<stdin>", line 4, in foo

__main__.FooError: invalid value: 0     --自己定义的错误

另一种错误处理方式——错误上抛

>>> def foo(s):

...    n = int(s)

...    if n == 0:

...         raise ValueError('invalid value: %s' %s)    --python内置错误

...    return 10 /n

...

>>> def bar():

...    try:

...        foo('0')

...    except ValueError as e:

...        print('ValueError')

...        raise    --raise语句如果不带参数,就会把当前错误原样抛出。

...

>>> bar()

ValueError

Traceback (most recent call last):

 File "<stdin>", line 1, in <module>

 File "<stdin>", line 3, in bar

 File "<stdin>", line 4, in foo

ValueError: invalid value: 0

其实这种错误处理方式不但没病,而且相当常见。捕获错误目的只是记录一下,便于后续追踪。但是,由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理。好比一个员工处理不了一个问题时,就把问题抛给他的老板,如果他的老板也处理不了,就一直往上抛,最终会抛给CEO去处理。

在except中raise一个Error,还可以把一种类型的错误转化成另一种类型

>>> try:

...    10 / 0

... except ZeroDivisionError:

...    raise ValueError('input error')

...

Traceback (most recent call last):

 File "<stdin>", line 2, in <module>

ZeroDivisionError: division by zero

During handling of the above exception,another exception occurred:

Traceback (most recent call last):

 File "<stdin>", line 4, in <module>

ValueError: input error

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • python 函数的初识

    py3study
  • python编程之函数思想

    py3study
  • python 的err输出BaseExc

    try: print('try...') r = 10 / 0 print('result:', r) except BaseException as e: p...

    py3study
  • 三分钟Python充电-解压可迭代对象赋值给多个变量

    """ 问题: 如果一个可迭代对象的元素个数超过变量个数时,会抛出一个ValueError,那么怎样才能从这个可迭代对象中解压出N个元素出来? 解决方案: P...

    石晓文
  • 用Golang构建gRPC服务

    继续之前,请确保你已经对gRPC概念有所了解,并且熟悉protocol buffer。需要注意的是教程中的示例使用的是 proto3版本的protocol bu...

    KevinYan
  • Go处理字符串到合法文件名

    flytam
  • Python科学计算 | NumPy——快速处理数据02

    除了前面介绍的ndarray数组对象和ufunc函数之外,NumPy还提供了大量对数组进行处理的函数。

    Sam Gor
  • python 入门知识拾遗

    Python 3最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。Pyt...

    py3study
  • 【解密】创造独特设计的十种方法

    我要告诉你如何避免陷入重复设计的陷阱,但仍然保留你的个人风格。这里有一些有创意的想法可供你尝试:

    用户1730674
  • KS检验及其在机器学习中的应用

    Kolmogorov–Smirnov 检验,简称KS检验,是统计学中的一种非参数假设检验,用来检测单样本是否服从某一分布,或者两样本是否服从相同分布。在单样本的...

    用户3577892

扫码关注云+社区

领取腾讯云代金券