• python异常处理



    title: python异常处理
    data: 2018-4-6
    categories:

    • python
      tags:
    • python

    try...except

    有时候写程序的时候,会出现一些错误或异常,导致程序终止。例如,做除法时,除数为0,会引起一个ZeroDivisionError

    a=10
    b=0
    c=a/b
    print("done")
    

    运行结果:

    Traceback (most recent call last):
    ...
    ZeroDivisionError: division by zero
    

    发现程序因为 ZeroDivisionError 而中断了,语句 print("done") 没有运行。为了处理异常,使用 try...except,更改代码:

    a=10
    b=0
    try:
        c=a/b
        print(c)
    except (ZeroDivisionError, TypeError) as e:
        print(e)
    print("done") 
    

    运行结果:

    division by zero
    done
    

    这样程序就不会因为异常而中断,从而 print("done") 语句正常执行。

    把可能发生错误的语句放在 try 模块里,用 except 来处理异常。except 可以处理一个专门的异常,也可以处理一组圆括号中的异常,如果 except 后没有指定异常,则默认处理所有的异常。每一个 try,都必须至少有一个 except

    处理一组异常可以这样写(其中e代表异常的实例):

    try:
        pass
    except (IOError, ZeroDivisionError) as e:
        print(e)
    

    Python 常见的标准异常类

    异常名称 描述
    Exception 所有异常的基类
    AttributeError 特征引用或者赋值失败时引发的
    IOError 试图打在不存在的文件(包括其他情况)
    IndexError 使用序列中不存在的索引
    KeyError 使用映射中不存在的键
    NameError 找不到名字(变量)
    SyntaxError 在代码为错误形式时引发
    SystemExit 系统异常退出
    TypeError 在内建操作或者函数应用与错误类型的对象时
    ValueError 正确的类型对象,但是对象使用不合适的值
    ZeroDivisionError 除法,第二参数为0

    捕捉异常

    基本形式:

    try:
        需要执行的操作
    except 异常类 as e:
        如果发生异常,执行以下代码
    else:
        如果没有发生异常,执行的命令
    finally:
        无论如何,都要执行的代码
    
    • 注意 except as e 的写法,e 是一个变量,记录了异常的类,可以用 print 函数打印出来
    • except 后面的异常类,建议写 Exception,这样就一定能捕获到异常。
    • 捕获到异常,就不会去执行 else 模块

    示例:

    try:
        name = input('Please input your name: ')
        print('Hello %s' %name)
        print(10/0)
    except Exception as e:
        print('Got an error ', e)
    else:
        print('OK')
    finally:
        print('Game over')
    
    Please input your name: zhong
    Hello zhong
    Got an error  division by zero
    Game over
    

    再举个例子:

    import urllib.request
    
    def main():
    	try:
    		response = urllib.request.urlopen("http://210.35.16.108")
    		# response = urllib.request.urlopen("https://www.baidu.com")
    	except Exception as e:
    		# raise
    		print(e)
    	else:
    		print('无异常则执行,有异常就不执行')
    	finally:
    		print('不管怎样,最后总会执行这行代码')
    
    if __name__ == '__main__':
    	main()
    

    结果:

    <urlopen error [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。>
    不管怎样,最后总会执行这行代码
    [Finished in 21.5s]
    

    捕获多个异常

    方法一:

    try:
        需要执行的操作
    except 异常类1 as e:
        如果发生异常类1,执行以下代码
    except 异常类2 as f:
        如果发生异常类2,执行以下代码
    else:
        如果没有发生异常,执行的命令
    finally:
        无论如何,都要执行的代码
    
    • except 后面的异常类,如果无需指定,直接写 Exception 即可。
    • 如果需要明确指定异常的类,而且是多个类的情况下,可以使用多个 except 语句。

    方法二:

    try:
        需要执行的操作
    except (异常类1,异常2,异常3) as e:
        如果发生异常,执行以下代码
    else:
        如果没有发生异常,执行的命令
    finally:
        无论如何,都要执行的代码
    

    抛出异常

    raise 关键字可以自主抛出异常,规则如下:

    raise NameError([str])

    • raise 后面跟异常的类,类括号里面,可以指定要抛出的异常示例,约详细越好
    >>> raise NameError()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError
    
    >>> raise NameError('bad name')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: bad name
    

    例如:

    # 当你输入的不是整数,它会报错(ValueError),但你输入的是一个整数后,它会输出你输入的整数。
    Q = input("请输入一个整数:")
    if type(Q) != type(1):
        raise ValueError
    else:
        print(Q)
    
    Q = input("请输入一个整数:")
    if type(Q) != type(1):
        raise leixingError("类型错误!")
    else:
        print(Q)
    

    总结如下

    1. except语句不是必须的,finally语句也不是必须的,但是二者必须要有一个,否则就没有try的意义了。
    2. except语句可以有多个,Python会按except语句的顺序依次匹配你指定的异常,如果异常已经处理就不会再进入后面的except语句。
    3. except语句可以以元组形式同时指定多个异常,参见实例代码。
    4. except语句后面如果不指定异常类型,则默认捕获所有异常,你可以通过logging或者sys模块获取当前异常。
    5. 如果要捕获异常后要重复抛出,请使用raise,后面不要带任何参数或信息。
    6. 不建议捕获并抛出同一个异常,请考虑重构你的代码。
    7. 不建议在不清楚逻辑的情况下捕获所有异常,有可能你隐藏了很严重的问题。
    8. 尽量使用内置的异常处理语句来替换try/except语句,比如with语句,getattr()方法。
  • 相关阅读:
    用Java redis 实现发送手机验证码的功能
    redis之Java Jedis 的使用(使用maven引入)
    设计模式之代理模式
    Redis相关配置
    Redis五大数据类型
    设计模式之享元模式
    设计模式之外观模式
    设计模式之组合模式
    设计模式之装饰者模式
    设计模式之适配器模式
  • 原文地址:https://www.cnblogs.com/id88/p/14210878.html
Copyright © 2020-2023  润新知