Python의 예외 메커니즘 이해

coldplay.xixi
풀어 주다: 2021-03-10 10:00:33
앞으로
2872명이 탐색했습니다.

서문: 이전에 작업할 때 Python을 사용하여 직렬 포트를 사용하여 SCPI를 보내고 마이크로 컨트롤러와 상호 작용하는 명령줄 창을 완성했습니다. 기능을 구현할 때 Python을 사용하여 최종 올바른 값 또는 데이터 결과의 잘못된 값 메인 인터페이스로 직접 돌아갈 수 있습니다. 분명히 다른 의미를 가진 데이터를 직접 반환하는 것은 불가능하므로, 잘못된 값을 가진 데이터를 처리하기 위해 예외 메커니즘이 사용됩니다. 이전에는 이상현상에 대해 잘 몰랐기 때문에 여기서 몇 가지 정보를 확인하고 몇 가지 메모를 정리했습니다.

Python의 예외 메커니즘 이해

기사 디렉토리

  • 1. 예외 이해하기
    • 1. 오류와 예외의 차이점
    • 3.
    • 2. 파이썬의 5가지 주요 예외 처리 메커니즘
  • 1. 기본 예외 처리 메커니즘
    • 2. try....exc...처리 메커니즘
    • 3. ..처리 메커니즘
    • 4. 어설션 처리 메커니즘
    • 5. 처리 메커니즘으로
    • 3. 예외 사용자 정의
  • 2. 3. 예외 캡처
    • 4. 예외 사용 시 주의 사항
    • 1. 예외 메커니즘에 너무 의존하지 마세요
    • 2. Done. 캡처된 예외를 무시하지 마세요
  • 요약
    • (무료 학습 권장 사항:
    python 비디오 튜토리얼
  • )

1. 예외의 이해1. 란 무엇입니까? 비정상비정상이란 "정상적인 상태와 다르다"는 뜻입니다. 정상이란 인터프리터가 코드를 해석할 때 우리가 작성한 코드가 인터프리터가 정의한 규칙을 준수한다는 것을 의미합니다. 즉, 인터프리터가 특정 코드 조각이 문법을 준수하지만 비정상일 수 있음을 발견하면 정상입니다. 인터프리터는 프로그램의 정상적인 실행을 방해하는 이벤트를 발생시킵니다. 이 중단된 신호는

비정상 신호

입니다. 따라서 전체적인 설명은 인터프리터가 프로그램에서 오류를 감지하면 예외를 생성하고 프로그램이 이를 처리하지 않으면 예외가 발생하고 프로그램이 종료된다는 것입니다. 빈 .py 파일에 int("m")를 쓸 수 있으며 실행 후 결과는 다음과 같습니다.

  이 글꼴 문자열은 인터프리터에서 발생하는 일련의 오류 메시지입니다. int()에 전달된 매개변수는 숫자 문자열과 숫자만 지원하므로 분명히 'm'은 전달된 매개변수에 속하지 않습니다. 가 잘못되었으므로 설명은 다음과 같습니다. 장치가 "valueError" 오류를 보고합니다.

2. 오류와 예외의 차이점

  Python 오류 개요:코드가 실행되기 전의 구문 또는 논리적 오류를 나타냅니다. 일반적인 구문 오류를 예로 들면, 우리가 작성한 코드가 구문 테스트를 통과하지 못하면 프로그램이 실행되기 전에 구문 오류가 직접 나타나며, 그렇지 않으면 작성된 코드가 실행되지 않습니다. 그리고 캡처할 수 없습니다. 예를 들어 a = 1 print("hello")가 .py 파일에 입력된 경우 출력 결과는 다음과 같습니다.

Traceback (most recent call last): File "E:/Test_code/test.py",line 1 if a = 1 print("hello") ^SyntaxError: invalid syntax
로그인 후 복사
 print() 함수에 콜론이 누락되어 오류가 있는 것으로 확인되었습니다. 파서는 구문 오류가 있는 코드 줄을 재현하고 작은 "화살표"를 사용하여 줄에서 감지된 첫 번째 오류를 가리킵니다. 따라서 해당 위치를 직접 찾고 구문을 수정할 수 있습니다. 물론, 문법적인 오류 외에도 메모리 오버플로 등의 프로그램 충돌 오류도 많이 있습니다. 이러한 오류는 상대적으로 숨겨져 있는 경우가 많습니다. 오류에 비해
Python 예외는 프로그램 실행 중 논리적 또는 알고리즘적 문제가 발생할 때 주로 발생합니다. 인터프리터가 이를 처리할 수 있으면 문제가 없으며 프로그램을 직접 종료하고 오류를 발생시킵니다. 첫 번째 지점의 int('m') 예제와 같은 예외는 매개변수가 잘못 전달되었기 때문에 프로그램 오류가 발생합니다. 논리로 인해 발생하는 모든 종류의 예외가 있습니다. 다행히도 우리 통역사에는 다양한 유형의 예외가 내장되어 있어 어떤 종류의 예외가 발생하는지 알 수 있으므로 "올바른 약을 처방"할 수 있습니다. Python의 예외 메커니즘 이해여기서 위의 구문 오류는 인식된 오류이므로 통역사도 기본적으로 SyntaxError 예외 메시지를 발생시켜 프로그래머에게 피드백합니다. 따라서 본질적으로 대부분의 오류는 출력 및 인쇄가 가능하지만 오류 코드가 실행되지 않기 때문에 처리할 수 없으므로 오류 예외 정보를 캡처하는 것이 의미가 없게 됩니다.

3. Python 예외의 일반적인 유형

  다음은 코드를 작성할 때 가장 일반적인 예외 유형입니다. 다른 유형의 예외가 발생하면 당연히 Baidu를 선택하세요~

二、python五大异常处理机制

  我们明白了什么是异常后,那么发现异常后怎么处理,便是我们接下来要解决的问题。这里将处理异常的方式总结为五种。

1、默认异常处理机制

  “默认”则说明是解释器默认做出的行为,如果解释器发现异常,并且我们没有对异常进行任何预防,那么程序在执行过程中就会中断程序,调用python默认的异常处理器,并在终端输出异常信息。刚才举过的例子:int(“m”),便是解释器因为发现参数传入异常,这种异常解释器“无能为力”,所以它最后中断了程序,并将错误信息打印输出,告诉码农朋友们:你的程序有bug!!!

2、try…except…处理机制

  我们把可能发生错误的语句放在try语句里,用except来处理异常。每一个try,都必须至少有一个或者多个except。举一个最简单的例子如下,在try访问number的第500个元素,很明显数组越界访问不了,这时候解释器会发出异常信号:IndexError,接着寻找后面是否有对应的异常捕获语句except ,如果有则执行对应的except语句,待except语句执行完毕后,程序将继续往下执行。如果没有对应的except语句,即用户没有处理对应的异常,这时解释器会直接中断程序并将错误信息打印输出

number = 'hello'try: print(number[500]) #数组越界访问except IndexError: print("下标越界啦!")except NameError: print("未声明对象!")print("继续运行...")
로그인 후 복사

输出结果如下,因为解释器发出异常信号是IndexError,所以执行下标越界语句。

下标越界啦! 继续运行...
로그인 후 복사

  为了解锁更多用法,我们再将例子改一下,我们依然在try访问number的第500个元素,造成访问越界错误,这里的except用了as关键字可以获得异常对象,这样子便可获得错误的属性值来输出信息。

number = 'hello'try: print(number[500]) #数组越界访问except IndexError as e: print(e)except Exception as e: #万能异常 print(e)except: #默认处理所有异常 print("所有异常都可处理")print("继续运行...")
로그인 후 복사

输出结果如下所示,会输出系统自带的提示错误:string index out of range,相对于解释器因为异常自己抛出来的一堆红色刺眼的字体,这种看起来舒服多了(能够“运筹帷幄”的异常才是好异常嘛哈哈哈)。另外这里用到“万能异常”Exception,基本所有没处理的异常都可以在此执行。最后一个except表示,如果没有指定异常,则默认处理所有的异常。

string index out of range继续运行...
로그인 후 복사

3、try…except…finally…处理机制

  finally语句块表示,无论异常发生与否,finally中的语句都要执行完毕。也就是可以很霸气的说,无论产生的异常是被except捕获到处理了,还是没被捕获到解释器将错误输出来了,都统统要执行这个finally。还是原来简单的例子加上finally语句块如下,代码如下:

number = 'hello'try: print(number[500]) #数组越界访问,抛出IndexError异常except IndexError: print("下标越界啦!")finally: print("finally!")print("继续运行...") #运行
로그인 후 복사

结果如下,数据越界访问异常被捕获到后,先执行except 语句块,完毕后接着执行了finally语句块。因为异常被执行,所以后面代码继续运行。

下标越界啦!finally! 继续运行...
로그인 후 복사

  对try语句块进行修改,打印abc变量值,因为abc变量没定义,所以会出现不会被捕获的NameError异常信号,代码如下所示:

number = 'hello'try: print(abc) #变量未被定义,抛出NameError异常except IndexError: print("下标越界啦!")finally: print("finally!")print("继续运行...") #不运行
로그인 후 복사

结果如下,因为NameError异常信号没法被处理,所以解释器将程序中断,并将错误信息输出,但这过程中依然会执行finally语句块的内容。因为程序被迫中断了,所以后面代码不运行。

finally! #异常没被捕获,也执行了finallyTraceback (most recent call last): File "E:/Test_code/test.py",line 3,in  print("abc")NameError: name 'abc' is not defined
로그인 후 복사
로그인 후 복사

  理解到这里,相信:try…finally…这种机制应该也不难理解了,因为省略了except 捕获异常机制,所以异常不可能被处理,解释器会将程序中断,并将错误信息输出,但finally语句块的内容依然会被执行。例子代码如下:

number = 'hello'try: print(abc) #变量未被定义,抛出NameError异常finally: print("finally!")print("继续运行...")
로그인 후 복사

运行结果:

finally! #异常没被捕获,也执行了finallyTraceback (most recent call last): File "E:/Test_code/test.py",line 3,in  print("abc")NameError: name 'abc' is not defined
로그인 후 복사
로그인 후 복사

4、assert断言处理机制

  assert语句先判断assert后面紧跟的语句是True还是False,如果是True则继续往下执行语句,如果是False则中断程序,将错误信息输出。

assert 1 == 1 #为True正常运行assert 1 == 2 #为False,终止程序,错误信息输出
로그인 후 복사

5、with…as处理机制

  with…as一般常用在文件处理上,我们平时在使用类似文件的流对象时,使用完毕后要调用close方法关闭,很麻烦,这里with…as语句提供了一个非常方便且人性的替代方法,即使突发情况也能正常关闭文件。举个例子代码如下,open打开文件后将返回的文件流对象赋值给fd,然后在with语句块中使用。

with open('e:/test.txt','r') as fd: fd.read() print(abc) #变量未被定义,程序终止,错误信息输出print("继续运行...")
로그인 후 복사

  正常情况下,这里的with语句块完毕之后,会自动关闭文件。但如果with语句执行中发生异常,如代码中的变量未定义异常,则会采用默认异常处理机制,程序终止,错误信息输出,后面代码不被运行,文件也会正常关闭。

三、python异常自定义

  说了这么多异常的使用,终于可以回到我前言所说的在实际项目中存在的问题,即错误码的返回和数值的返回是冲突的(因为错误码也是数值),这时候便可以用异常的抛出和捕获来完成错误码的传递,即try和except 。但系统发生异常时抛出的是系统本身定义好的异常类型,跟自己的错误码又有何关系?这就是我接下来要说的内容:如何定义自己的异常并且能够被except 所捕获

1、异常自定义

  实际开发中,有时候系统提供的异常类型往往都不能满足开发的需求。这时候就要使用到异常的自定义啦,你可以通过创建一个新的异常类来拥有自己的异常。自己定义的异常类继承自 Exception 类,可以直接继承,或者间接继承。栗子举起来:

class MyException(Exception): '''自定义的异常类''' def __init__(self, error_num): #异常类对象的初始化属性 self.error_num = error_num def __str__(self): #返回异常类对象说明信息 err_info = ['超时错误','接收错误'] return err_info[self.error_num]
로그인 후 복사

  该类继承自Exception 类,并且新类的名字为MyException,这跟前面我们一直在用的IndexError这个异常类一样,都是继承自Exception 类。__init__为构造函数,当我们创建对象时便会自动调用,__str__为对象说明信息函数,当使用print输出对象的时候,只要自己定义了__str__方法,那么就会打印从在这个方法中return的数据。
  即print(MyException(0))时,便可打印“超时错误”这个字符串,print(MyException(1))时,便可打印“接收错误”这个字符串,心细的你应该可以理解,MyException(x)为临时对象(x是传入错误码参数,这里只定义了0和1),与a = MyException(x),a为对象一个样子 。这里有一个好玩的说法,在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法。

2、异常抛出raise

  现在我们自己定义的错误定义好了(上面的MyException),怎么能像IndexError一样让except捕获到呢?于是乎raise关键字派上用场。我们在异常机制中用try…except时,一般都是将可能产生的错误代码放到try语句块中,这时出现异常则系统便会自动将其抛出,比如IndexError,这样except就能捕获到,所以我们只要将自定义的异常在需要的时候将其抛出即可。
  raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类),那么我们刚刚定义的异常类就可以用啦,举个简单例子:

try: raise MyException(0) # 自己定义的错误类,将错误码为0的错误抛出except MyException as e: print(e) # 输出的是__str__返回的内容,即“超时错误”
로그인 후 복사

  这里我直接将自己定义的错误抛出,…as e就是把得到的错误当成对象e,这样才可以访问其属性和方法。因为自己定义的错误中可以支持多个错误码(本质还是MyException这个错误),所以便可实现传入不同错误码就可打印不同错误信息。

3、异常捕获

  只要我们在try中将错误raise出来,except就可以捕获到(当然,异常必须是Exception 子类才能被捕获),将前面两个例子整合起来,代码如下:

'''错误码:0代表超时错误,1代表接收错误'''class MyException(Exception): '''自定义的异常类''' def __init__(self, error_num): # 异常类对象的初始化属性 self.error_num= error_num def __str__(self): # 返回异常类对象指定错误码的信息 err_info = ['超时错误','接收错误'] return err_info[self.error_num]def fun() raise MyException(1) # 抛出异常对象,传入错误码1def demo_main(): try: fun() except MyException as ex: # 这里要使用MyException进行捕获,对象为ex print(ex) # 输出的是__str__部分返回的内容,即“接收错误” print(ex.error_num) # 输出的是__init__中定义的error_num,即1demo_main() #此处开始运行
로그인 후 복사

  代码从demo_main函数开始执行,进入try语句块,语句块中的fun()函数模拟代码运行失败时raise 自定义的异常,except 正常接收后通过as 关键字得到异常对象,访问该异常对象,便可正常输出自定义的异常信息和自定义的错误码。

四、异常使用注意事项

此注意事项参考博文:异常机制使用细则.

1、不要太依赖异常机制

  python 的异常机制非常方便,对于信息的传递中十分好用(这里信息的传递主要有三种,参数传递,全局变量传递,以及异常机制传递),但滥用异常机制也会带来一些负面影响。过度使用异常主要表现在两个方面:①把异常和普通错误混淆在一起,不再编写任何错误处理代码,而是以简单地引发异常来代苦所有的错误处理。②使用异常处理来代替流程控制。例子如下:

buf = "hello"#例1:使用异常处理来遍历arr数组的每个元素try: i = 0 while True: print (buf [i]) i += 1except: pass#例2:使用流程控制避免下标访问异常i = 0while i < len(buf ): print(buf [i]) i += 1
로그인 후 복사

  例1中假如循环过度便会下标访问异常,这时候把错误抛出,再进行一系列处理,显然是不可取的,因为异常机制的效率比正常的流程控制效率差,显然例2中简单的业务流程就可以避开这种错误。所以不要熟悉了异常的使用方法后,遇到这种简单逻辑,便不管三七二十一引发异常后再进行解决。对于完全己知的错误和普通的错误,应该编写处理这种错误的代码,增加程序的健壮性。只有对于外部的、不能确定和预知的运行时错误才使用异常

2、不要在 try 块中引入太多的代码

try 블록에 많은 코드를 배치하는 것은 "간단"해 보이고 코드 프레임워크도 이해하기 쉽습니다. 그러나 try 블록의 코드가 너무 크고 비즈니스가 너무 복잡하기 때문에다음과 같은 가능성이 있습니다. try 블록의 예외가 크게 증가하여 이상 원인을 분석하기가 더 어려워졌습니다.
  그리고 블록이 너무 크면 다양한 예외에 대해 서로 다른 처리 논리를 제공하기 위해 많은 수의 제외 블록이 있는 try 블록을 따라야 하는 것이 불가피합니다. 동일한 try 블록 뒤에 많은 수의 제외 블록이 따라오는 경우 이들 사이의 논리적 관계를 분석해야 하므로 프로그래밍 복잡성이 증가합니다. 따라서큰 try 블록을 여러 개의 작은 블록으로 분할한 다음 각각 예외를 포착하고 처리할 수 있습니다.

3. 잡힌 예외를 무시하지 마세요

 예외를 무시하지 마세요! 이제 예외가 포착되었으므로제외 블록은 유용한 작업을 수행하고 예외를 처리하고 수정해야 합니다. 블록을 제외한 전체를 비워두거나, 단순 예외 정보만 출력하는 것은 부적절합니다! 구체적인 처리 방법은 다음과 같습니다.
예외 처리.예외를 적절하게 수정한 다음 예외가 발생한 곳을 우회하여 계속 실행하거나 예상된 메서드 반환 값 대신 다른 데이터를 사용하여 계산을 수행하거나 사용자에게 프로그램을 다시 실행하라는 메시지를 표시합니다. 프로그램이 작업을 재개할 수 있도록 예외를 복구해야 합니다.
새로운 예외를 다시 발생시킵니다.현재 실행 중인 환경에서 할 수 있는 일을 최대한 완성한 뒤, 예외를 번역하고, 현재 계층의 예외로 패키징한 후 상위 계층 호출자에게 다시 전달합니다.
적절한 레이어에서 예외를 처리하세요
. 현재 계층에서 예외 처리 방법을 모르는 경우 현재 계층에서 예외 문을 사용하여 예외를 포착하지 말고 상위 계층 호출자가 예외 처리를 담당하도록 하세요.

요약

 이 문서는 시스템의 기본 예외로 시작하여 예외가 무엇인지 설명하고 시스템의 일반적인 예외 클래스를 요약한 다음 예외 정의부터 발생, 사용자 지정 예외 가져오기까지 예외를 사용자 지정하는 방법을 작성합니다. .예외의 정의와 사용법을 정의하고, 마지막으로 파이썬 예외를 사용할 때의 주의사항을 요약합니다.

관련 무료 학습 권장 사항:python 튜토리얼(동영상)

위 내용은 Python의 예외 메커니즘 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:csdn.net
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!
ㅋㅋㅋ 유니코드 오류 유니코드 관련 오류 UnicodeDecodeError Unicode 디코딩 오류 UnicodeEncodeError Unicode 인코딩 중 오류 UnicodelateError 유니코드 변환 오류 전쟁 ning 경고용 기본 클래스 DeprecationWarning 사용되지 않는 기능에 대한 경고 FutureWarning 미래에 의미가 변경되는 구문에 대한 경고 OverflowWarning long으로 자동 승격에 대한 오래된 경고 PendingDepre cationWarning 기능에 대한 경고 감가 상각 된 runtImewarning suspicious 런타임 동작 경고 경고 syntaxwarning Suspificate 구문 경고 userWarning ring ranging auser code
예외 이름 이름 확인
BaseException 모든 예외의 기본 클래스
SystemExit 통역사 요청 종료
KeyboardInter rupt 사용자가 실행을 중단합니다(보통 ^C 입력) )
Exception 일반 오류 기본 클래스
StopIteration Iterator에 더 이상 값이 없습니다.
GeneratorExit 종료를 알리기 위해 생성기에서 예외가 발생했습니다
StandardError 모두를 위한 기본 클래스 내장된 표준 예외
ArithmeticError 모든 수치 계산 오류에 대한 기본 클래스
FloatingPointError 부동 소수점 계산 오류
OverflowError 수치 연산이 최대 한도를 초과했습니다.
ZeropisionError 나누기(또는 모듈로) 0(모든 데이터 유형)
AssertionError Assertion 문 실패
AttributeError 객체에 이 속성이 없습니다
EOFError 내장 입력 없음, EOF 플래그
EnvironmentError 운영 체제 오류 기본 클래스
IOError 입/출력 작업 실패
OSError 운영 체제 오류
WindowsError에 도달했습니다. 시스템 호출 실패
ImportError 모듈/개체를 가져오지 못했습니다.
LookupError 잘못된 데이터 쿼리 기본 클래스
IndexError No such index in 순서
KeyError Map 해당 키가 없습니다
메모리 오류 메모리 부족 오류(Python 인터프리터의 경우 치명적이지 않음)
NameError 선언되지 않은/초기화된 객체(속성 없음)
UnboundLocalError 초기화되지 않은 지역 변수 액세스
ReferenceError 약한 참조 시도 가비지 수집된 개체에 액세스
RuntimeError 일반 런타임 오류
NotImplementedError 아직 구현되지 않은 메서드
SyntaxError Python 구문 오류
들여쓰기 오류 들여쓰기 오류