Python #22 l 파이썬 날개달기_예외처리(Exception)

신승호·2021년 3월 25일
0

Python

목록 보기
23/35
post-custom-banner

List

  • 파이썬 날개달기
    • 클래스(class)
    • 모듈(module)
    • 패키지(package)
    • 예외처리(exception)
    • 내장함수
    • 라이브러리(library)
    • 연습문제

파이썬 날개달기_예외처리(Exception)


오류는 어떤 때 발생하는가?

디렉터리 안에 없는 파일을 열려고 시도했을 때

  • FileNotFoundError 오류 발생
>>> f = open("나없는파일", 'r')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '나없는파일'

0으로 다른 숫자를 나누는 경우

  • ZeroDivisionError 오류 발생
>>> 4 / 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

리스트에 없는 값을 구할 때

  • IndexError 오류 발생
>>> a = [1,2,3]
>>> a[4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

오류 예외 처리 기법

try, except문의 기본구조

  • 기본구조
try:
    ...
except [발생 오류[as 오류 메시지 변수]]:
    ...
  • **try블록 수행 중 오류 발생 하면 except블록 수행 하고
  • **try블록 수행 중 오류 발생 하지 않으면 except블록 수행 안함

except 문

  • try문, except문만 사용
    • 오류 종류에 상관없이 try블록 수행 중 오류발생하면 except블록 수행
try:
    ...
except:
    ...
  • 발생 오류만 포함한 except문
    • 미리 정해놓은 오류 이름과 일치할때 만 except 블록 수행
try:
    ...
except 발생 오류:
    ...
  • 발생오류오류 메세지 변수까지 포함한 except문
    • 오류 메세지의 내용 까지 알고싶을 때 사용
try:
    ...
except 발생 오류 as 오류 메시지를 나타낼 변수:
    ...
try:
    4 / 0
except ZeroDivisionError as e:		# 오류가 발생이 되고 실행되는 변수 e에 오류 메세지가 담기고 e를 프린트 한다.
    print(e)				# 오류메세지(오류메세지를 나타내는 변수가 e이기 때문에)를 출력하시오
>>> division by zero

try . . finally

finally절try문 수행도중 예외 발생 여부에 상관없이 항상 수행된다.

  • 보통 사용한 리소스를 close해야할 때 사용
    • f = open(‘xx.txt’, ‘r or w’)로 열고 f.close()로 닫는다.
f = open('foo.txt', 'w')
try:
    # 무언가를 수행한다.
finally:
    f.close()

여러개의 오류 처리

  • except문 추가
try:
    ...
except 발생 오류1:
   ... 
except 발생 오류2:
   ...
try:
    a = [1,2]
    print(a[3])
    4/0
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다.")
except IndexError:
    print("인덱싱 할 수 없습니다.")
>>> “인덱싱 할 수 없습니다.”       #  리스트에 없는 값을 요청했기 때문에 인덱싱 오류가 발생되고 / 인덱싱 오류가 먼저 발생하여 ZeroDivisionError 오류는 발생하지 않음
try:
    a = [1,2]
    print(a[3])
    4/0
except ZeroDivisionError as e:
    print(e)
except IndexError as e:		# as사용하여 오류메세지 출력
    print(e)
>>> “list index out of range”
  • except문 에서 오류 묶기
try:
    ...
except (발생 오류1, 발생 오류2, …) :
   ... 
>>> try:
    a = [1,2]
    print(a[3])
    4/0
except (ZeroDivisionError, IndexError) as e:
    print(e)

    
list index out of range
  • try문else절 사용
try:
    ...
except [발생 오류[as 오류 메시지 변수]]:
    ...
else:  # 오류가 없을 경우에만 수행된다.
    ...
try:
    age=int(input('나이를 입력하세요: '))           
except:
    print('입력이 정확하지 않습니다.')
else:
    if age <= 18:
        print('미성년자는 출입금지입니다.')
    else:
        print('환영합니다.')
*** 숫자가 아닌 다른 값을 입력하면 오류가 발생하여 '입력이 정확하지 않습니다.'라는 문장을 출력한다. 오류가 없을 경우에만 else절이 수행된다.

오류 회피하기

  • pass 사용
try:
    f = open("나없는파일", 'r')
except FileNotFoundError:
    pass

오류를 일부로 발생시키기

오류를 일부로 발생시켜야 할 경우도 생긴다

  • raise 명령어 사용
class Bird:
    def fly(self):
        raise NotImplementedError
*** Bird 클래스를 상속받는 자식 클래스는 fly 함수를 다시 작성(구현)해야 한다

※ NotImplementedError는 파이썬 내장 오류로, 꼭 작성해야 하는 부분이 구현되지 않았을 경우 일부러 오류를 일으키기 위해 사용

  • 클래스 상속을 했을 때에도 NotImplementedError를 발생시키면 상속이 안되는것 그렇기 때문에 따로 구현을 다시 해야한다.
  • 부모 클래스 상속한 자식클래스가 fly함수를 따로 구현하지 않고 호출한다면 NotImplementedError 오류가 뜬다.
class Eagle(Bird):
    pass
>>> eagle = Eagle()
>>> eagle.fly()
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    eagle.fly()
  File "<pyshell#1>", line 3, in fly
    raise NotImplementedError
NotImplementedError
  • 그렇기 때문에 다시 자식 클래스 에서 fly함수를 재 작성(구현)해줘야 한다.
>>>class Eagle(Bird):
         def fly(self):
             print("very fast")
>>>eagle = Eagle()
>>>eagle.fly()
very fast

예외 만들기

Exception 클래스 상속

파이썬 내장클래스인 Exception클래스를 상속하여 만든다.

  • 기본구조
class MyError(Exception):
    pass
    
def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick)

say_nick("천사")
say_nick("바보")
  • 천사를 먼저 출력 후 MyError이 발생
천사
Traceback (most recent call last):
  File "...", line 11, in <module>
    say_nick("바보")
  File "...", line 7, in say_nick
    raise MyError()
__main__.MyError

예외 처리 기법

  • 오류 메세지 사용
class MyError(Exception):
    pass

def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick)

try:
    say_nick("천사")
    say_nick("바보")
except MyError:
    print("이거 아니라고 ㅡ ㅡ ")
천사
이거 아니라고 ㅡ ㅡ 
  • 오류 메세지 사용 / 하지만 이것은 오류메세지가 뜨지 않을 것임
    • 왜냐하면 MyError 클래스pass로 해놓아서 암꺼도 안할꺼고 뭘 지정해줘야함.
class MyError(Exception):
    pass

def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick)
    
try:
    say_nick("천사")
    say_nick("바보")
except MyError as e:
    print(e)
  • 위는 오류 메세지가 출력 되지 않을 것임, MyError클래스에 __str__ 메서드를 구현(작성)해야함

  • 참고로 문자를 위한 메서드는 __str__ / 숫자를 필요로한 메서드는 __int__를 사용한다.

class MyError(Exception):
	def __str__(self):
    	return "허용되지 않는 별명입니다."

def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick)
    
try:
    say_nick("천사")
    say_nick("바보")
except MyError as e:
    print(e)
천사
허용되지 않는 별명입니다.
profile
신승홉니다
post-custom-banner

0개의 댓글