출처: 파이썬 공식문서 8장 오류와 예외처리.
https://docs.python.org/3/tutorial/errors.html#raising-exceptions
(영어버전 한국어로 번역기 돌려서 어색한 부분만 고침)
지금까지 오류 메시지는 언급될 뿐이었지만, 예제를 시도해 본 적이 있다면 몇 가지를 보았을 것입니다.
구별할 수 있는 두 가지 종류의 오류가 있습니다 : 구문 오류 와 예외
8.1. 구문 오류(Syntax Errors)
구문 오류 (parsing errors 라고도 함) 는 아마도 Python을 배우는 동안 가장 흔한 불만 중 하나입니다.
while True print('Hello world')
File "<stdin>", line 1
while True print('Hello world')
^
SyntaxError: invalid syntax
파서(컴파일러의 일부로, 컴파일러나 인터프리터에서 원시 프로그램을 읽어드려, 그 문장의 구조를 알아내는 구문 분석을 해결할 수 있는 단위)는 잘못된 줄을 반복하고 가장 먼저 오류가 감지된 줄에서 화살표를 가리킵니다. 이 오류는 화살표 앞에 있는 토큰에서 발생합니다(또는 최소한 감지됩니다):
예제에서는 함수 print()에서 오류가 발생합니다. while줄에 콜론(':')이 누락되어 있기 때문입니다. 스크립트에서 입력이 왔을 경우 어디를 봐야 하는지를 알려주기 위해 파일 이름과 줄 번호가 인쇄됩니다.
8.2. 예외(Exceptions)
문장 또는 표현이 구문상 올바르더라도, 실행 시도 중에 오류가 발생할 수 있습니다. 실행 중 발견된 오류를 예외 라고 하며, 반드시 치명적인 것은 아닙니다. 이러한 예외를 Python 프로그램에서 처리하는 방법을 곧 배우게 됩니다. 그러나 대부분의 예외는 프로그램에서 처리되지 않으며, 다음과 같은 오류 메시지가 표시됩니다:
10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
#0으로 나눴을 때 나타나는 오류
4 + spam*3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
#spam의 변수가 정의되지 않았을 때 나타나는 오류
'2' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
#문자열과 정수형을 함께 더하려고 할 때 나타나는 오류.
#파이썬에서는 서로 다른 자료형을 더할 수 없다.
#문자열과 정수형을 함께 사용하려면 문자열과 정수형을 각각 문자열로 변환한 뒤 더해주어야 한다.
오류 메시지의 마지막 줄은 무슨 일이 일어났는지를 나타냅니다. 예외는 다양한 타입으로 나뉘며, 이 타입은 메시지의 일부로 출력됩니다. 예제에서 타입은 ZeroDivisionError, NameError, TypeError입니다. 출력된 예외 타입 문자열은 발생한 내장 예외의 이름입니다. 모든 내장 예외에 대해 이렇게 출력되지만, 사용자 정의 예외에 대해서는 그렇지 않을 수 있습니다(하지만 유용하게 참고할 수 있음). 표준 예외 이름은 내장 식별자(예약된 키워드가 아님)입니다.
라인의 나머지 부분은 예외의 타입과 그것이 발생한 원인에 따라 상세 정보를 제공합니다.
오류 메시지의 앞부분은 스택 추적(traceback)의 형식으로 예외가 발생한 문맥을 보여줍니다. 일반적으로, 소스 라인을 나열하는 스택 추적을 포함하고 있지만, 표준 입력에서 읽은 라인은 표시하지 않습니다.
내장 예외(Built-in Exceptions)는 내장 예외와 그 의미를 나열합니다.
8.3. 예외 처리(Handling Exceptions)
선택한 예외를 처리하는 프로그램을 작성할 수 있습니다.
다음 예제를 살펴봅시다. 이 예제는 사용자로부터 유효한 정수가 입력될 때까지 입력을 요청하지만, 프로그램을 중단할 수 있도록 합니다(운영 체제에서 지원하는 Control-C 또는 기타 방법을 사용). 사용자가 발생시킨 중단은 KeyboardInterrupt 예외를 발생시켜 신호를 보냅니다.
while True:
try:
x = int(input("Please enter a number: "))
break
except ValueError:
print("Oops! That was no valid number. Try again...")
try 문은 다음과 같은 방식으로 작동합니다.
- 먼저 try 절 (try와 except 키워드 사이의 문장) 이 실행됩니다.
- 예외가 발생하지 않으면 except 절은 건너뛰고 try 문의 실행이 끝납니다.
- try 절 실행 중 예외가 발생하면, 이후 문장은 건너뛰게 됩니다. 그 후, 예외의 타입이 except 키워드 뒤에 지정된 예외 이름과 일치하면 except 절이 실행됩니다. 그리고나서 try/except 블록 이후의 실행이 계속됩니다.
- except 절에서 지정된 예외 이름과 일치하지 않는 예외가 발생하면, 이는 외부 try 문으로 전달됩니다. 이 경우, 예외를 처리하는 핸들러가 없으면, 실행이 멈추고 위에서 본 메시지처럼 결과가 출력됩니다.
try 문은 여러 except 절을 가질 수 있습니다. 가장 많이 하나의 핸들러만 실행됩니다. 핸들러는 해당 try 절에서 발생한 예외만 처리합니다. 다른 try 문 핸들러에서 발생한 예외는 처리하지 않습니다. except 절은 괄호로 묶인 튜플로 여러 예외를 지정할 수 있습니다.
except (RuntimeError, TypeError, NameError):
pass
8.4.예외 일으키기(Raising Exceptions)
raise 문은 프로그래머가 지정된 예외가 발생하도록 강제할 수 있습니다. 예를 들어 다음과 같이 할 수 있습니다:
raise NameError('HiThere')
#Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
#NameError: HiThere
raise의 유일한 인수는 발생할 예외를 나타냅니다. 이는 예외 인스턴스 또는 예외 클래스 (예를 들어 Exception 또는 이를 상속한 클래스와 같이 BaseException에서 파생된 클래스) 중 하나여야 합니다.
raise ValueError
# 'raise ValueError()'의 약식
예외가 발생했는지 여부를 결정하지만 처리하지 않을 경우,
예외를 다시 발생시키는 간단한 형식의 raise 문을 사용하여 예외를 다시 발생시킬 수 있습니다:
try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
raise
#An exception flew by!
#Traceback (most recent call last):
# File "<stdin>", line 2, in <module>
#NameError: HiThere
이 뒤의 내용은 클래스에 관련된 예외처리 내용이여서 생략..(사실 클래스는 안배워서 그런가 이해가 아직 안 됨)
그래서 이 내용을 적용하여 행맨 함수를 다시 만들어보았다.
+ 준혁스의 아이디어 추가(한국어 한 글자를 예외처리하는 방법)
1. input()으로 받은 문자를 upper, lower로 바꿔 비교한다.
한국어는 바뀌지 않으니 예외처리 가능
2. valueError 에러 사용해 try 문을 사용해 예외처리한다.
여기서 두번째 방법을 사용해서 처리해 봤다.
교수님이 말씀해주신 ord()가 기억속에서 희미~ 해졌는데 여기서 쓰게될줄은,,,,
while True: # 극강의 예외처리
try:
user_guess = input("글자를 유추하세요: ").lower()
if len(user_guess) != 1 or not user_guess.isalpha() or ord(user_guess) < ord('a') or ord(
user_guess) > ord('z'):
raise ValueError
break
except ValueError:
print("알파벳 한 글자로만 입력하세요")
continue
다른 코드에도 적용해봐야 확실히 알 것 같다.
일단 함수 공부를 한 후에 예외처리를 다시 공부하는 걸로!!
'개발공부 > Python' 카테고리의 다른 글
[파이썬] 숫자야구 함수화해서 만들기 (0) | 2023.04.26 |
---|---|
[파이썬] 60갑자 조합 만들어보기 (0) | 2023.04.24 |
[파이썬] 로보77게임 만들기(순서도, 1차코드, 미완) (0) | 2023.04.22 |
[파이썬] 행맨 게임 만들기( while, random, if, isalpha(), random 활용) (0) | 2023.04.21 |
[파이썬] UP & DOWN 게임 만들기(while, for, if, random, isdigit 사용) (0) | 2023.04.21 |