소개
이 랩에서는 효과적인 오류 처리에 필수적인 기술인, Python 에서 예외가 특정 유형인지 확인하는 방법을 배우게 됩니다. 이 랩은 예외 계층 구조를 이해하고 이 지식을 활용하여 특정 예외 유형을 식별하는 데 중점을 둡니다.
이 랩은 BaseException 기본 클래스와 Exception과 같은 하위 클래스부터 시작하여 Python 예외 계층 구조를 탐구하도록 안내합니다. Python 스크립트 exception_hierarchy.py를 생성하여 예외 계층 구조를 출력함으로써 다양한 예외 클래스 간의 관계를 시각화할 수 있습니다. 그런 다음, isinstance() 및 직접적인 클래스 비교를 사용하여 예외 유형을 확인하는 후속 단계에서 이 이해를 적용하게 됩니다.
예외 계층 구조 이해
이 단계에서는 Python 의 예외 계층 구조에 대해 배우게 됩니다. 이 계층 구조를 이해하는 것은 효과적인 오류 처리에 매우 중요합니다. Python 의 예외는 트리 구조로 구성되어 있으며, 맨 위에 기본 클래스가 있고, 더 구체적인 예외 클래스가 이를 상속받습니다.
모든 예외의 기본 클래스는 BaseException입니다. BaseException에서 직접 상속되는 클래스는 Exception, GeneratorExit, KeyboardInterrupt, 그리고 SystemExit입니다. Exception 클래스는 프로그램에서 발생할 수 있는 오류를 나타내는 대부분의 내장 예외의 슈퍼클래스입니다.
이 계층 구조를 탐구하기 위해 Python 스크립트를 만들어 보겠습니다.
VS Code 편집기를 엽니다.
~/project디렉토리에exception_hierarchy.py라는 새 파일을 생성합니다.~/project/exception_hierarchy.pyexception_hierarchy.py파일에 다음 코드를 추가합니다.def print_exception_hierarchy(exception_class, indent=0): """Prints the exception hierarchy starting from a given exception class.""" print(' ' * indent + str(exception_class)) for subclass in exception_class.__subclasses__(): print_exception_hierarchy(subclass, indent + 1) print("Exception Hierarchy:") print_exception_hierarchy(Exception)이 스크립트는
Exception클래스부터 시작하여 예외 계층 구조를 출력하는 재귀 함수print_exception_hierarchy를 정의합니다.터미널에서 다음 명령을 사용하여 스크립트를 실행합니다.
python exception_hierarchy.py이렇게 하면 예외 계층 구조의 트리 구조가 터미널에 출력됩니다.
예시 출력:
Exception Hierarchy: <class 'Exception'> <class 'ArithmeticError'> <class 'FloatingPointError'> <class 'OverflowError'> <class 'ZeroDivisionError'> <class 'decimal.DivisionByZero'> <class 'AssertionError'> <class 'AttributeError'> <class 'BufferError'> <class 'EOFError'> <class 'ImportError'> <class 'ModuleNotFoundError'> <class 'ZipImportError'> <class 'LookupError'> <class 'IndexError'> <class 'KeyError'> <class 'tracemalloc.DomainKey'> <class 'MemoryError'> <class 'NameError'> <class 'UnboundLocalError'> <class 'OSError'> <class 'BlockingIOError'> <class 'ChildProcessError'> <class 'ConnectionError'> <class 'BrokenPipeError'> <class 'ConnectionAbortedError'> <class 'ConnectionRefusedError'> <class 'ConnectionResetError'> <class 'FileExistsError'> <class 'FileNotFoundError'> <class 'InterruptedError'> <class 'InterruptedSystemCall'> <class 'IsADirectoryError'> <class 'NotADirectoryError'> <class 'PermissionError'> <class 'ProcessLookupError'> <class 'TimeoutError'> <class 'UnsupportedOperation'> <class 'itertools.Incomplete'> <class 'signal.ItimerError'> <class 'ReferenceError'> <class 'RuntimeError'> <class 'NotImplementedError'> <class 'asyncio.exceptions.IncompleteReadError'> <class 'zlib.error'> <class '_frozen_importlib._DeadlockError'> <class 'RecursionError'> <class 'StopAsyncIteration'> <class 'StopIteration'> <class 'SyntaxError'> <class 'IndentationError'> <class 'TabError'> <class 'SystemError'> <class 'TypeError'> <class 'ValueError'> <class 'UnicodeError'> <class 'UnicodeDecodeError'> <class 'UnicodeEncodeError'> <class 'UnicodeTranslateError'> <class 'Warning'> <class 'BytesWarning'> <class 'DeprecationWarning'> <class 'EncodingWarning'> <class 'FutureWarning'> <class 'ImportWarning'> <class 'PendingDeprecationWarning'> <class 'ResourceWarning'> <class 'RuntimeWarning'> <class 'SyntaxWarning'> <class 'UnicodeWarning'> <class 'UserWarning'>이 출력은
Exception을 기본 클래스로 하고 다양한 하위 클래스가 특정 유형의 오류를 나타내는 예외의 계층 구조를 보여줍니다. 이 계층 구조를 이해하면 적절한 세분성 수준에서 예외를 잡는 데 도움이 됩니다. 예를 들어,ZeroDivisionError와 같은 특정 예외 또는ArithmeticError(ZeroDivisionError의 상위 클래스) 와 같은 더 일반적인 예외를 잡을 수 있습니다.
예외에 isinstance() 사용
이 단계에서는 isinstance() 함수를 사용하여 예외가 특정 클래스 또는 클래스 튜플의 인스턴스인지 확인하는 방법을 배우게 됩니다. 이는 다양한 유형의 예외를 유연하게 처리하는 데 유용합니다.
isinstance() 함수는 두 개의 인수를 받습니다: 객체와 classinfo. 객체가 classinfo 의 인스턴스이거나 하위 클래스의 인스턴스인 경우 True를 반환합니다. 그렇지 않으면 False를 반환합니다.
예외와 함께 isinstance() 사용법을 시연하기 위해 Python 스크립트를 만들어 보겠습니다.
VS Code 편집기를 엽니다.
~/project디렉토리에isinstance_exception.py라는 새 파일을 생성합니다.~/project/isinstance_exception.pyisinstance_exception.py파일에 다음 코드를 추가합니다.try: result = 10 / 0 except Exception as e: if isinstance(e, ZeroDivisionError): print("Caught a ZeroDivisionError!") elif isinstance(e, ArithmeticError): print("Caught an ArithmeticError!") else: print("Caught some other exception!") print("Program continues...")이 스크립트에서는 10 을 0 으로 나누려고 시도하며, 이는
ZeroDivisionError를 발생시킵니다. 그런 다음 예외를 잡고isinstance()를 사용하여ZeroDivisionError또는ArithmeticError의 인스턴스인지 확인합니다.터미널에서 다음 명령을 사용하여 스크립트를 실행합니다.
python isinstance_exception.py이렇게 하면 "Caught a ZeroDivisionError!"가 터미널에 출력됩니다.
예시 출력:
Caught a ZeroDivisionError! Program continues...출력은
isinstance()함수가 예외를ZeroDivisionError의 인스턴스로 올바르게 식별했음을 보여줍니다.ZeroDivisionError는ArithmeticError의 하위 클래스이므로 첫 번째if조건이 충족되고 해당 메시지가 출력됩니다.이제 더 일반적인 예외를 잡도록 스크립트를 수정해 보겠습니다.
isinstance_exception.py파일을 다음과 같이 수정합니다.try: result = int("abc") except Exception as e: if isinstance(e, ZeroDivisionError): print("Caught a ZeroDivisionError!") elif isinstance(e, ValueError): print("Caught a ValueError!") elif isinstance(e, ArithmeticError): print("Caught an ArithmeticError!") else: print("Caught some other exception!") print("Program continues...")이 수정된 스크립트에서는 문자열 "abc"를 정수로 변환하려고 시도하며, 이는
ValueError를 발생시킵니다.동일한 명령을 사용하여 스크립트를 다시 실행합니다.
python isinstance_exception.py이렇게 하면 "Caught a ValueError!"가 터미널에 출력됩니다.
예시 출력:
Caught a ValueError! Program continues...이 출력은
isinstance()를 사용하여 서로 다른 유형의 예외를 구별하고 그에 따라 처리할 수 있음을 보여줍니다.
예외 클래스로 확인
이 단계에서는 except 블록에서 특정 예외 클래스를 직접 확인하는 방법을 배우게 됩니다. 이는 isinstance()를 사용하는 것보다 더 직접적이고 종종 더 명확한 예외 처리 방법입니다.
except ExceptionType as e:를 사용하면 ExceptionType 유형 또는 해당 하위 클래스인 예외만 잡도록 Python 에 지시하는 것입니다.
이를 시연하기 위해 Python 스크립트를 만들어 보겠습니다.
VS Code 편집기를 엽니다.
~/project디렉토리에exception_classes.py라는 새 파일을 생성합니다.~/project/exception_classes.pyexception_classes.py파일에 다음 코드를 추가합니다.try: result = 10 / 0 except ZeroDivisionError as e: print("Caught a ZeroDivisionError:", e) except ArithmeticError as e: print("Caught an ArithmeticError:", e) except Exception as e: print("Caught some other exception:", e) print("Program continues...")이 스크립트에서는 10 을 0 으로 나누려고 시도하며, 이는
ZeroDivisionError를 발생시킵니다.ZeroDivisionError,ArithmeticError, 그리고Exception에 대한 세 개의except블록이 있습니다.터미널에서 다음 명령을 사용하여 스크립트를 실행합니다.
python exception_classes.py이렇게 하면 "Caught a ZeroDivisionError: division by zero"가 터미널에 출력됩니다.
예시 출력:
Caught a ZeroDivisionError: division by zero Program continues...출력은
ZeroDivisionError가 첫 번째except블록에 의해 잡혔음을 보여줍니다.이제 다른 예외를 발생시키도록 스크립트를 수정해 보겠습니다.
exception_classes.py파일을 다음과 같이 수정합니다.try: result = int("abc") except ZeroDivisionError as e: print("Caught a ZeroDivisionError:", e) except ValueError as e: print("Caught a ValueError:", e) except ArithmeticError as e: print("Caught an ArithmeticError:", e) except Exception as e: print("Caught some other exception:", e) print("Program continues...")이 수정된 스크립트에서는 문자열 "abc"를 정수로 변환하려고 시도하며, 이는
ValueError를 발생시킵니다.동일한 명령을 사용하여 스크립트를 다시 실행합니다.
python exception_classes.py이렇게 하면 "Caught a ValueError: invalid literal for int() with base 10: 'abc'"가 터미널에 출력됩니다.
예시 출력:
Caught a ValueError: invalid literal for int() with base 10: 'abc' Program continues...이 출력은
ValueError가 두 번째except블록에 의해 잡혔음을 보여줍니다.except블록에서 예외 클래스를 직접 지정함으로써, 명확하고 체계적인 방식으로 다양한 유형의 예외를 처리할 수 있습니다. 이 접근 방식은 간단한 예외 처리를 위해isinstance()를 사용하는 것보다 일반적으로 선호됩니다.
요약
이 랩에서는 효과적인 오류 처리에 중요한 Python 의 예외 계층 구조를 탐구했습니다. 예외가 BaseException을 기본 클래스로, 대부분의 내장 예외에 대한 Exception을 슈퍼클래스로 하는 트리 구조로 구성되어 있음을 배웠습니다.
Exception 클래스부터 시작하여 예외 계층 구조를 출력하는 Python 스크립트 exception_hierarchy.py를 만들었습니다. 스크립트를 실행하여 예외의 트리 구조와 관계를 관찰함으로써 Python 에서 예외가 어떻게 구성되는지에 대한 더 나은 이해를 얻었습니다.



