파이썬은 에러를 다양한 클래스로 나누어 정의합니다.
파이썬보다 자바스크립트를 먼저 접해본 저에게
가장 어리둥절한 부분 중 하나가 바로 이 파이썬의 에러처리였습니다.
자바스크립트였으면 처리되었을 코드인데,
파이썬에서는 툭하면 에러를 뱉고 프로세스가 죽어버리죠.
javascript
console.log(10/0)
// 결과: Infinity
typeof(Infinity)
// 결과: 'number'
python
print(10/0)
# 결과: ZeroDivisionError: division by zero
javascript
console.log(1+'1')
//결과: '11'
python
print(1+'1')
#결과: TypeError: unsupported operand type(s) for +: 'int' and 'str'
그 외에도 파이썬에는 다양한 종류의 built-in 에러가 존재합니다.
docs.python.org/3/library/exceptions.html#exception-hierarchy
자바스크립트에서 예외처리를 할때는
간단하게 if else만 사용해도 작동합니다.
const data = {}
if (data['users']) {
console.log(data['users'])
} else {
console.log('유저 정보 없음');
};
//결과: '유저 정보 없음'
하지만 파이썬으로 같은 방식의 코드를 짜면 문제가 발생합니다.
data = {}
if data['users']:
print(data['users'])
else:
print('유저 정보 없음')
# 결과: KeyError: 'users'
위 코드를 파이썬으로 구현하기 위해서는 try except가 필요합니다.
data = {}
try:
print(data['users'])
except:
print('유저 정보 없음')
# 결과: '유저 정보 없음'
except 뒤에 특정 예외상황을 적어주면 해당 except문은 그 예외상황만을 처리합니다.
data = {}
try:
print(data['users'])
except KeyError:
print('유저 정보 없음')
# 결과: '유저 정보 없음'
except문은 예외상황별로 여러개 설정해놓을 수 있습니다.
import sys
try:
array = [0,1,2]
index_1, index_2 = map(int, input().split())
x = array[index_1] + array[index_2]
print(x)
except ValueError:
print('입력값이 올바르지 않습니다')
except IndexError:
print('인덱스가 범위를 벗어났습니다')
except:
print('기타 에러:', sys.exc_info()[0])
1. 우선 try문이 실행됩니다.
2. 예외가 발생되지 않으면 except문은 실행되지 않고 try문 안에서 종료됩니다.
3. 예외가 발생하면 바로 해당 예외상황의 except문으로 넘어갑니다.
(위의 경우 print(x)는 실행되지 않습니다)
4. 마지막에 예외 종류 이름을 생략한 except문은 와일드카드 역할을 합니다.
하지만 이 와일드카드를 사용하면 프로그래밍 에러를 가려낼 수 없게 되기도 하니 주의해서 써야 합니다.
except 에러클래스 as 변수
를 사용하면 변수안에 좀 더 명확한 에러메세지를 담을 수 있습니다.
import sys
try:
array = [0,1,2]
index_1, index_2 = map(int, input().split())
x = array[index_1] + array[index_2]
print(x)
except ValueError as e:
print(e)
except IndexError as e:
print(e)
except:
print('기타 에러:', sys.exc_info()[0])
예를 들면, 아래 코드는 input값으로 string을 넣어도, input값을 세 개 이상 넣어도
항상 동일한 '입력값이 올바르지 않습니다' 라는 메세지를 출력합니다.
try:
array = [0,1,2]
index_1, index_2 = map(int, input().split())
x = array[index_1] + array[index_2]
print(x)
except ValueError:
print('입력값이 올바르지 않습니다')
하지만 except 에러클래스 as 변수 를 쓰면
입력값이 어떻게 올바르지 않은지를 알 수 있습니다.
try:
array = [0,1,2]
index_1, index_2 = map(int, input().split())
x = array[index_1] + array[index_2]
print(x)
except ValueError as e:
print(e)
예외상황이 발생하지 않았을시 실행되는 코드는 else로 처리합니다.
else문은 모든 except의 뒤에 와야 합니다.
else는, 예외처리를 원하지 않는 코드까지 예외처리 되는 상황을 막습니다.
import sys
try:
array = [0,1,2]
index_1, index_2 = map(int, input().split())
x = array[index_1] + array[index_2]
except ValueError as e:
print(e)
except IndexError as e:
print(e)
except:
print('기타 에러:', sys.exc_info()[0])
else:
print(x)
에러가 발생하든 안하든 처리할 코드를 넣어줍니다.
try:
f = open('file.txt', 'r')
except OSError as e: #파일이 존재하지 않는다면
print(e)
else: #파일이 존재한다면
original_lines = f.readlines() #파일 내용 기억해두기
print(*original_lines, sep='\n') #파일 내용 출력하기
f.close() #파일 닫기
finally:
print('지금까지 준비한 내용은 여기까지입니다!')
위 코드는 file.txt 파일이 없어도 finally문을 실행합니다.
raise를 사용하면 직접 예외를 지정해서 발생하도록 할 수도 있습니다.
raise는 특히 논리적 오류에 대한 핸들링에 주로 사용됩니다.
user_id = 'dumdum_123'
user_pw = 'pass12word34'
try:
id_ = input('id를 입력해주세요: ')
if id_ != user_id:
raise Exception('id가 일치하지 않습니다')
pw_ = input('비밀번호를 입력해주세요: ')
if pw_ != user_pw:
raise Exception('비밀번호가 일치하지 않습니다')
except Exception as e:
print(e)
else:
print(f'환영합니다 {id_} 고객님')
사용자 정의 에러를 만들어내는 방법 중 assert를 사용하는 방법이 있습니다.
아래 코드는 지정된 조건이 거짓일때 AssertionError 에러를 발생시킵니다.
user_id = 'dumdum_123'
user_pw = 'pass12word34'
id_ = input('id를 입력해주세요: ')
assert user_id == id_, 'id가 일치하지 않습니다'
pw_ = input('비밀번호를 입력해주세요: ')
assert user_pw == pw_, '비밀번호가 일치하지 않습니다'
print(f'환영합니다 {id_}고객님')
참고
dojang.io/mod/page/view.php?id=2398
docs.python.org/ko/3/tutorial/errors.html#syntax-errors
python.bakyeono.net/chapter-9-4.html
[python]함수의 인자 형태와 순서 / (non)default value parameter, *args, **kwargs (0) | 2021.03.17 |
---|---|
[Python] 문자열을 붙이는 다양한 방법 (string concatenation) (1) | 2021.03.17 |
파이썬 매직 메소드(던더 메소드) (2) | 2021.02.28 |
가변객체(mutable)와 불변객체(immutable) / 파이썬 (2) | 2021.02.19 |
객체지향 프로그래밍과 그 특징(추상화, 캡슐화, 상속성, 다형성) / 파이썬 예시 (2) | 2021.02.19 |
댓글 영역