티스토리 뷰

프로그래밍을 하다보면 수 많은 오류들과 맞닥들이게 된다. 이러한 오류들은 파이썬에서 어떻게 처리하는지 알아보도록 하자.




오류 예외 종류



다양한 오류가 존재한다. 예외 클래스들의 계층도이다. 이는 파이썬 공식 홈페이지에서 발췌한 내용이다.


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
           +-- ResourceWarning


BaseException이라는 클래스를 부모로 하여 상속을 받아서 계층적으로 정리되어 있다. 그냥 봐도 상당히 다양한 예외들이 존재한다. 따라서 몇 가지 자주 발생하는 오류만 정리해 보도록 하겠다. 지극히 주관적으로 선택한 것이니 참고만하기 바란다.



ZeroDivisionError


어떤 값을 0으로 나누게 되면 발생하는 에러이다.


ValueError


데이터 타입이 맞지 않을 때 발생하는 에러이다.


FileNotFoundError


파일을 찾을 수 없을 때 발생하는 에러이다.


IndexError


리스트와 같이 인덱싱 된 데이터에서 존재하지 않는 인덱스의 값을 접근했을 때 발생하는 에러이다.


ModuleNotFoundError


모듈을 찾을 수 없을 때 발생하는 에러이다.


NotImplementError


구현화되지 않은 함수가 존재하면 발생하는 에러이다.



아직 파이썬에대한 경험과 지식이 깊지 않아서 일단 이정도로만 정리해 봤다. 더 추가해 가도록 하겠다.




오류 예외 처리



어떤 오류와 예외가 존재하는지 알아 보았으므로 본격적으로 예외 처리 방법에 대해서 정리해 보도록 하겠다. 아래의 코드를 예시로 하나씩 설명하도록 하겠다.


# zerodivision.py
try:
    num1 = int(input("input fisrt number: "))
    num2 = int(input("input second number: "))
    result = num1/num2
except ZeroDivisionError as e:
    print(e)
except ValueError as ev:
    print(ev)
else:
    print(result)
finally:
    print("file close")


try


이 안에있는 코드들을 실행하면서 오류가 발생하는지 검사한다. 따라서 오류발생의 우려가 있는 코드를 try문에 넣는다.



except [오류 as 오류 변수]


여기서는 try문에서 발생한 특정 오류에 따라서 실행되는 코드이다. 따라서 위의 예시에서는 ZeroDivisionError가 발생하면 그 에러는 e라는 변수에 저장되고 에러를 출력하는 동작을 한다.


마찬가지로 ValueError가 발생하면 그 에러는 ev라는 변수에 저장되고 에러를 출력하는 동작을 한다.



else


이 부분은 어떠한 오류나 예외가 발생하지 않았을 경우 실행되는 것이다. 따라서 정상 작동시 실행되는 부분이며, 만드시 except아래에 와야한다는 특징이 있다.



finally


이 부분은 예외와 상관없이 항상 실행되는 부분이다. 대표적으로 파일을 다룰 때 예외가 갑작스럽게 발생하더라도 close()를 안전하게 실행하기 위하여 자주 사용된다.



위 코드의 실행결과를 간단하게 보고 가도록 하자.



1. ZeroDivisionError 발생 결과

input fisrt number: 3
input second number: 0
division by zero
file close


두 번째 수가 0이라는 입력을 받아서 0으로 나누게 되면 ZeroDivisionError가 발생하게 된다. 따라서 에러를 출력하게 되고 finally문은 예외와 상관없이 실행하게 된다.



2. ValueError 발생 결과

input fisrt number: 30
input second number: ㅁㄴㅇㄹ
invalid literal for int() with base 10: 'ㅁㄴㅇㄹ'
file close


정수형의 데이터 타입대신 문자를 입력하게 되면 ValueError가 발생하게 된다. 따라서 위와 같이 에러를 출력하게 되고 finally문은 역시나 실행되는 모습이다.



3. 정상 실행 결과

input fisrt number: 30
input second number: 10
3.0
file close


위 결과는 정상적으로 프로그램이 실행된 것이다. 따라서 정상 실행된 경우 else문 내의 코드가 실행되어 계산 결과값을 출력하고 finally문은 성공시에도 실행되는 것을 볼 수 있다.




오류 회피



어떤 오류를 무시하고 싶을 때가 있을 것이다. 그럴 때는 다음과 같이 작성한다.


#pass.py
try:
    f = open("hello.txt", 'r')
except FileNotFoundError:
    pass


위 코드를 실행하게 되면 hello.txt라는 파일이 존재하지 않아서 FileNotFoundError가 발생해도 pass라는 명령어를 만나서 무시하고 넘어가게 된다.




오류 강제로 발생시키기



특정한 상황에서 오류를 직접 발생하고 싶다면 raise명령어를 사용한다. 생각보다 강제로 오류를 발생시키는 코딩방법이 많이 사용된다고 한다. 다음 예시를 보자.


# raise.py
class Student:
    def study(self):
        raise NotImplementedError

class Yun(Student):
    pass

yun = Yun()
yun.study()


위의 예시는 Student라는 클래스가 존재하며 Yun이라는 클래스는 Student 클래스를 상속받고 있다. 따라서 Yun이라는 클래스의 인스턴스인 yun에서 study()를 호출하면 Student클래스의 study가 실행되어 구현화 되지 않았을 때 발생하는 NotImplementedError를 강제로 발생하게 된다.


Traceback (most recent call last):
  File "C:/Users/hyoje/PycharmProjects/Practice/raise.py", line 10, in 
    yun.study()
  File "C:/Users/hyoje/PycharmProjects/Practice/raise.py", line 4, in study
    raise NotImplementedError
NotImplementedError


따라서 자식 클래스에서 함수를 구현화 해준다면 이는 해결될 수 있다.


# raise.py
class Student:
    def study(self):
        raise NotImplementedError

class Yun(Student):
    def study(self):
        print("study hard!")
yun = Yun()
yun.study()


위와 같이 Yun 클래스에서 study함수를 구현해주면 아래와 같은 결과를 얻을 수 있다.


study hard!


이와 같이 구현화할 함수를 강제하고 싶을 때 이렇게 오류를 강제로 발생시키는 방법을 사용할 수 있다.




참고



https://docs.python.org/ko/3/library/exceptions.html

https://python.bakyeono.net/chapter-9-4.html

점프 투 파이썬 - 박응용

'Programming > Python' 카테고리의 다른 글

[Python]__init__.py  (2) 2019.03.09
[Python]if __name__ == "__main__"  (11) 2019.03.07
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함