Python 异常处理 详解_python sys.out.error-程序员宅基地

技术标签: python  Python  

1、错误和异常

1.1 错误 Error

  • 逻辑错误:算法写错了,例如加法写成了减法
  • 笔误:例如变量名写错了,语法错误
  • 函数或类使用错误:其实这也属于逻辑错误
  • 总之,错误是可以避免的

1.2 异常 Exception

  • 异常就是意外情况
  • 在没有出现上述错误的前提下,也就是说程序写的没有问题,但是在某些情况下,会出现一些意外,导致程序无法正常执行下去
  • 例如,访问一个网络文件,突然断网了,这就是个异常,是个意外的情况
  • 总之,异常是不可能避免的

1.3 总结

  • 错误和异常:在高级编程语言中,一般都有错误和异常的概念,异常是可以捕获的,并被处理的,但是错误是不能被捕获的
  • 一个健壮的程序,尽可能的避免错误,尽可能的捕获、处理各种异常

2、产生异常

  • 1 raise 语句显式的抛出异常

  • 2 Python 解释器自己检测到异常并引发它

  • 3 程序会在异常抛出的地方中断执行,如果不捕获,就会提前结束程序(其实是终止当前线程的执行)

    def foo():
        print('before')
        print(1/0)  # 捕获异常 
        print('after')
    
    foo()
    # ZeroDivisionError: division by zero
    
    def foo():
        print('before')
        raise Exception('My Exception')  # raise 主动抛出异常 
        print('after')
    
    foo()
    # Exception: My Exception
    

3、捕获异常

3.1 语法

try:
    待捕获异常的代码块
except [异常类型]:
    异常的处理代码块

3.2 示例 1

  • 此例执行到c = 1/0时产生异常并抛出,由于使用了try...except语句块则捕捉到了这个异常

  • 异常生成位置之后语句块将不再执行,转而执行对应的except部分的语句

  • 最后执行try...except语句块之外的语句

    def foo():
        try:
            print('before')
            c = 1/0
            print('after')
        except:
            print('error')
            
        print('catch the exception')
    
    foo()
    print('====== end ======')
    
    before
    error
    catch the exception
    ====== end ======
    

3.3 示例 2

def foo():
    try:
        print('before')
        print(1/0)
        print('after')
    except ArithmeticError:  # 指定捕获的类型
        print('error')

    print('catch the exception')

foo()
print('====== end ======')
before
error
catch the exception
====== end ======

4、 异常类

4.1 Exception hierarchy

The class hierarchy for built-in exceptions is:
BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      |    +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- EncodingWarning
           +-- ResourceWarning

4.2 BaseException及子类

  • BaseException:所有内建异常类的基类是 BaseException
  • SystemExitsys.exit()函数引发的异常,异常不捕获处理,就直接交给Python解释器,解释器退出
  • KeyboardInterrupt:对应的捕获用户中断行为 Ctrl + C
  • Exception及子类:
    1、 Exception是所有内建的、非系统退出的异常的基类,自定义异常类应该继承自它
    2、 SyntaxErrorPython将这种错误也归到异常类下面的Exception下的子类,但是这种错误是不可捕获的
    3、 ArithmeticError:所有算术计算引发的异常,其子类有除零异常等
    4、 LookupError:使用映射的键或序列的索引无效时引发的异常的基类:IndexError, KeyError
    5、 自定义异常类:从Exception继承的类

4.3 sys.exit()示例 1

import sys
KeyboardInterrupt
print('Before')
sys.exit(1)
print('SysExit')
print('outer')
D:\PycharmProjects\pythonProject\202108089\venv\Scripts\python.exe D:/PycharmProjects/pythonProject/202108089/test6.py
Before

Process finished with exit code 1

4.4 sys.exit()示例 2

import sys

try:
    sys.exit(1)
except SystemExit:
    print('SysExit')
print('outer')
D:\PycharmProjects\pythonProject\202108089\venv\Scripts\python.exe D:/PycharmProjects/pythonProject/202108089/test6.py
SysExit
outer

Process finished with exit code 0

4.5 KeyboardInterrupt示例

try:
    import time
    while True:
        time.sleep(1)
        print('!!!')
except KeyboardInterrupt:
    print('Ctrl + C')
print('=== end ===')
PS D:\PycharmProjects\pythonProject\202108089> python .\test8.py
!!!
!!!
Ctrl + C
=== end ===
PS D:\PycharmProjects\pythonProject\202108089>

4.6 SyntaxError示例

  • 语法错误直接报错,无法捕捉,解释器连执行都不会去做
try:
    0a = 5
except SyntaxError:  # 无法捕获
    print('after')
SyntaxError: invalid syntax
print('=' * 10)
def 0a():
    print('begin')

try:
    0a()
except Exception as e:
    print(e, type(e))
D:\PycharmProjects\pythonProject\202108089\venv\Scripts\python.exe D:/PycharmProjects/pythonProject/202108089/test8.py
  File "D:/PycharmProjects/pythonProject/202108089/test8.py", line 1
    def 0a():
        ^
SyntaxError: invalid syntax

Process finished with exit code 1

4.7 自定义类示例

class MyException(Exception):
    pass

try:
    raise MyException
except MyException:  # 捕捉自定义异常
    print('Catch the exception')

Out:
Catch the exception

5、多种捕获

多种捕获:except可以指定捕获的类型,捕获多种异常。

5.1 捕获规则

  • 1 捕获是从上到下依次比较,如果匹配,则执行匹配的except的语句块
  • 2 如果被一个except语句捕获,其它except语句就不会再次捕获了,谁在前谁捕获
  • 3 如果没有任何一个except语句捕获到这个异常,则该异常向外抛出
  • 4 捕获原则:从小到大,从具体到宽泛
  • 5 编写异常时:越具体的异常,越往上写;宽泛的,往下写;尽量不要压制异常

5.2 示例 1

import sys

class MyException(Exception):
    pass

try:
    print('before')
    a = 1/0
#     raise MyException()
#     open('t')
#     sys.exit(1)

except MyException:
    print('catch my exception')
except ArithmeticError:  # 可以捕获除零异常
    print('ari')
except ZeroDivisionError:  # 可以捕获除零异常
    print('zero')
except MyException:
    print('catch my exception')
except BaseException:  # 可以捕获除零异常
    print('Base')
except Exception:  # 可以捕获除零异常
    print('exception')
except:
    print('sysexit')

5.3 示例 2

class A:pass

try: 
    raise A()
except:
    print('catch the exception')

Out:
catch the exception

6、其它子句介绍

  • as子句:被抛出的异常,应该时异常类的实例,可以使用as子句获得这个对象
  • raise语句:raise后要求应该是BaseException类的子类或实例,如果是类,将被无参实例化;raise后什么都没有,表示抛出最近一个被激活的异常,如果没有被激活的异常,则抛出类型异常;raise是用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是ErrorException类的子类
  • Python用异常对象(exception object)表示异常情况,遇到错误后,会引发异常
  • 如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(Traceback,一种错误信息)终止执行
  • finally子句:最终,即最后一定要执行的,try...finally语句块中,不管是否发生了异常,都要执行finally的部分
  • else子句:没有任何异常发生,则执行

6.1 示例 1

class MyException(Exception):
    def __init__(self, code, message):
        self.code = code
        self.message = message

try: 
    raise MyException()
    raise 1/0
    # raise
except MyException as e:
    print('catch my exception')
except Exception as e:
    print(e)
    print('=== end ===')

Out:
__init__() missing 2 required positional arguments: 'code' and 'message'
=== end ===

6.2 示例 2

class MyException(Exception):
    def __init__(self, code, message):
        self.code = code
        self.message = message

try: 
    # raise MyException()
    raise 1/0
    # raise
except MyException as e:
    print('catch my exception')
except Exception as e:
    print(e)
    print('=== end ===')

Out:
division by zero
=== end ===

6.3 示例 3

f = None
try:
    f = open('111.txt')
except Exception as e:
    print(e.__class__, e.errno, e.strerror)
finally:
    print('clear working')
    try:
        f.close()
    except Exception as e:
        print(e)

Out:
<class 'FileNotFoundError'> 2 No such file or directory
clear working
'NoneType' object has no attribute 'close'

6.4 示例 4

# 函数的返回值取决于最后一个执行的return语句,而finally则是try...finally中最后执行的语句块

def foo():
    # return 1
    try:
        return 3
    finally:
        return 5
        print('Finally')
    print('===')
    
print(foo())

Out:
5

6.5 示例 5

try:
    ret = 1/0
    # ret = 1 * 0
except ArithmeticError as e:
    print(e)
else:
    print('OK')
finally:
    print('fin')
division by zero
fin

6.6 示例 6

try:
    # ret = 1/0
    ret = 1 * 0
except ArithmeticError as e:
    print(e)
else:
    print('OK')
finally:
    print('fin')
OK
fin

7、异常的传递

7.1 示例 1

  • foo2调用了foo1foo1产生的异常,传递到了foo2

  • 异常总是向外层抛出,如果外层没有处理这个异常,就会继续向外抛出

  • 如果内层捕获并处理了异常,外部就不能捕获到了

  • 如果到了最外层还是没有被处理,就会中断异常所在的线程的执行

  • 注意整个程序结束的状态返回值

    def foo1():
        return 1/0
    
    def foo2():
        print('foo2 start')
        foo1()
        print('foo2 stop')
    
    foo2()
    
    D:\PycharmProjects\pythonProject\202108089\venv\Scripts\python.exe D:/PycharmProjects/pythonProject/202108089/test6.py
    Traceback (most recent call last):
    	... ...
        return 1/0
    ZeroDivisionError: division by zero
    foo2 start
    
    Process finished with exit code 1
    

7.2 示例 2

# 线程中测试异常
import threading
import time

def foo1():
    return 1/0

def foo2():
    time.sleep(3)
    print('foo2 start')
    foo1()
    print('foo2 stop')
    
t = threading.Thread(target=foo2)
t.start()

while True:
    time.sleep(1)
    print('Everything is OK.')
    print(threading.enumerate())

8、try语句

8.1 try 语法

try:
    <语句>  # 运行别的代码
except <异常类>:
    <语句>  # 捕获某种类型的异常
except <异常类> as <变量名>:
    <语句>  # 捕获某种类型的异常并获得对象
else:
    <语句>  # 如果没有异常发生
finally:
    <语句>  # 退出try时总会执行

8.2 try 工作原理

  • 1 如果try中语句执行时发生异常,搜索except子句,并执行第一个匹配该异常的except子句
  • 2 如果try中语句执行时发生异常,却没有匹配的except的子句,异常将被递交到外层的try,如果外层不处理这个异常,异常将继续向外层传递。如果都不处理该异常,则会传递到最外层,如果还没有处理,就终止异常所在的线程
  • 3 如果在try执行时没有发生异常,如有else子句,可执行else子句中的语句
  • 4 无论try中是否发生异常,finally子句最终都会执行

8.3 示例 1

# try嵌套
# 内部捕获不到异常,会向外层传递异常
# 但是如果函数内层有finally且其中有return break语句,则异常就不会继续向外抛出
try:
    try:
        ret = 1/0
    except KeyError as e:
    # except ZeroDivisionError as e:
        print(e)
    finally:
        print('inner fin')
except:
    print('outer catch')
finally:
    print('outer fin')
inner fin
outer catch
outer fin

8.4 示例 2

# try嵌套
# 内部捕获不到异常,会向外层传递异常
# 但是如果函数内层有finally且其中有return break语句,则异常就不会继续向外抛出
def foo():
    try:
        ret = 1/0
    except KeyError as e:
        print(e)
    finally:
        print('inner fin')
        return

try:
    foo()
except:
    print('outer catch')
finally:
    print('outer fin')
inner fin
outer fin

9、异常的捕获时机

  • 1 立即捕获:需要立即返回一个明确的结果

  • 2 边界捕获:封装产生了边界

    def parse_int(s):
        try:
            return int(s)
        except:
            return 0
    
    print(parse_int('s'))
    
    Out:
    0
    

10、自定义异常类注意事项

10.1 异常类写的有问题

# 自己写的异常类没写对,抛出异常,被exception捕获

class MyException(Exception):
    def __init__(self, code, msg):
        self.code = code
        self.msg = msg
    
try:
    raise MyException  # 抛出的异常都是实例
except NotImplementedError as e:
    print('not imp', e, type(e))
except MyException as e:
    print('my exception', e, type(e))
except Exception as e:
    print('all exception', e, type(e))
    
print('end')
all exception __init__() missing 2 required positional arguments: 'code' and 'msg' <class 'TypeError'>
end

10.2 异常类传入参数

class MyException(Exception):
    def __init__(self, code, msg):
        self.code = code
        self.msg = msg
    
try:
    raise MyException(999, '123')
except NotImplementedError as e:
    print('not imp', e, type(e))
except MyException as e:
    print('my exception', e, type(e))
except Exception as e:
    print('all exception', e, type(e))
    
print('end')
my exception (999, '123') <class '__main__.MyException'>
end

10.3 异常类传入默认参数

class MyException(Exception):
    def __init__(self, code="200", msg="Not OK"):
        self.code = code
        self.msg = msg
    
try:
    raise MyException  # 等效于raise MyException()
except NotImplementedError as e:
    print('not imp', e, type(e))
except MyException as e:
    print('my exception', e, type(e), e.code)
except Exception as e:
    print('all exception', e, type(e))
    
print('end')
my exception  <class '__main__.MyException'> 200
end
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44983653/article/details/123952213

智能推荐

centos 安装python3/pip3/sqlite3步骤详解_centos yum python3 sqlite3-程序员宅基地

文章浏览阅读1.6k次。题记项目的需要需要在python3下部署环境,且不能破坏python2的正常业务运行。 当安装sqlite3的时候,出现过各种异常。网上排查了很久。 记录下来,避免下次犯同样的错误。1、安装python3安装版本:Python-3.5.01步骤1: 准备编译环境yum groupinstall 'Development Tools'y..._centos yum python3 sqlite3

TSD相关的 4 个函数: pthread_key_create(); pthread_key_delete(); pthread_getspecific(); pthread_sets_pthread_key_delete pthread_key_create-程序员宅基地

文章浏览阅读1.4k次。在多线程程序中,经常要用全局变量来实现多个函数间的数据共享。由于数据空间是共享的,因此全局变量也为所有进程共有。但有时应用程序设计中必要提供线程私有的全局变量,这个变量仅在线程中有效,但却可以跨过多个函数访问。比如在程序里可能需要每个线程维护一个链表,而会使用相同的函数来操作这个链表,最简单的方法就是使用同名而不同变量地址的线程相关数据结构。这样的数据结构可以由 Posix 线程库维护,成_pthread_key_delete pthread_key_create

Traits技术-程序员宅基地

文章浏览阅读1.7k次。Traits技术traits=特性提取不同类的共性,统一处理依靠显示模板特殊化,把代码中因不同类型发生变化的片段提取出,用统一的接口来包装接口可以为c++类所能包含的任何东西客户通过traits模板类公开的接口来间接访问代码示例#include <iostream>using namespace std;class CIntArray{..._traits技术

使用python出现错误 urlopen error unknown url type: https 的解决办法-程序员宅基地

文章浏览阅读1.7w次。分析 这个错误和python的中ssl (Secure Sockets Layer,一种国际标准的加密与身份认证通讯协议)模块有一定关系,成功安装了ssl模块,就可以解决这个问题。解决方法 Windows系统和其他类Unix系统略有不同,但是都可以确认一下使用的python版本中是否安装了ssl模块,在python环境中使用以下命令查看已安装的模块..._urlopen error unknown url type

chrome浏览器88版本隐藏webdriver方法_哪个软件可以让webdriver不显示浏览器-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏2次。隐藏webdriver最近不小心把chrome浏览给升级了,然后前几天有用到selenium去访问某宝。就除了一些问题,,,然后找了半天原因,说是要把selenium中的webdriver属性给隐藏才行。然后跟着其他大佬的教程改了一下,大部分都是说在访问之前添加这句代码Object.defineProperty(navigator, 'webdriver', { get: () =>undefined })然后我跟着做,结果发现还是不能隐藏。然后我在虚拟机中尝试了一下,发现可以,结果是un_哪个软件可以让webdriver不显示浏览器

python123第三周答案_Python123第二周自由练习-程序员宅基地

文章浏览阅读490次,点赞2次,收藏3次。一、画五角星描述画一个五角星,画笔用黄色,用红色填充,效果如下所示。 ‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬代码如下:#画五角星import turtleturtle.pensize(5)turtle.pencolor("yellow")turt..._绘制一组同心圆,如下图所示。三个圆的半径依次为20、40、60。画笔粗细为5,颜色为

随便推点

Kubernetes基础4_dashboard-metrics-scraper-7f7574cd55-9l8jc" is wai-程序员宅基地

文章浏览阅读1.9k次。1.HPA控制器简介1 方式1:手动调整pod数量,通过kubectl scale命令临时修改方式,不会持久保存查看pod 数量root@master1:~# kubectl get pod -A -o widens-uat uat-tomcat-app1-deployment-677fcd9d44-jxmfm 1/1 Running 4 5d10h 10.20.2.57 172.16.62.20_dashboard-metrics-scraper-7f7574cd55-9l8jc" is waiting to start: trying and

java/php/node.js/python基于微信小程序的河南省美食分享平台【2024年毕设】-程序员宅基地

文章浏览阅读25次。本系统带文档lw万字以上文末可领取本课题的JAVA源码参考。

一文了解Linux内核-程序员宅基地

文章浏览阅读5.6k次,点赞15次,收藏136次。本文来自 [https://www.ssdfans.com]目录什么是操作系统OS操作系统的的组成什么是内核kernel内核的操作内核的分类Linux操作系统Linux内核内核源码结构Linux内核与硬件的关系是什么使Linux内核与其他经典Unix内核不同?Linux内核架构Linux内核接口Linux可加载内核模块 (The Linux Loadable Kernel Module (LKM) )什么是操作系统OS操作系统(简称..._linux内核

Android事件分发机制_setonlicklistener-程序员宅基地

文章浏览阅读228次。Android事件分发机制一、Android分发机制概述: Android如此受欢迎,就在于其优秀的交互性,这其中,Android优秀的事件分发机制功不可没,那么,作为一个优秀的程序员,要想做一个具有良好交互性的应用,必须透彻理解Android的事件分发机制。 要想充分理解android的分发机制,需要先对以下几个知识点有所了解: 1、View_setonlicklistener

45个值得收藏的 CSS 形状(总结)_css 矩形大全-程序员宅基地

文章浏览阅读242次。CSS能够生成各种形状。正方形和矩形很容易,因为它们是 web 的自然形状。添加宽度和高度,就得到了所需的精确大小的矩形。添加边框半径,你就可以把这个形状变成圆形,足够多的边框半径,你就可以把这些矩形变成圆形和椭圆形。我们还可以使用 CSS 伪元素中的::before和::after,这为我们提供了向原始元素添加另外两个形状的可能性。通过巧妙地使用定位、转换和许多其他技巧,我们可以只用一个 HTML 元素在 CSS 中创建许多形状。虽然我们现在大都使用字体图标或者svg图片,似乎使用 CSS ..._css 矩形大全

POJ二分匹配总结_匈牙利算法_poj f = 2*n + n*logn-程序员宅基地

文章浏览阅读3.2k次。二分匹配模板bool makepair(int t){ int i; for(i=1;i<=n;i++) { if(path[t][i]==1 && visited[i]==0) //i号男还没被需要并且和t号女互相喜欢 { visited[i]=1; //被t号女需要 if(match[i]==-1_poj f = 2*n + n*logn

推荐文章

热门文章

相关标签