파이썬 개발자 들은 유틸리티 함수를 작성할 때 반환 값을 None으로 하면서 이 값에 특별한 의미를 부여하려는 경향을 보인다.
경우에 따라서는 이 결정이 타당할 수 있다.
def careful_divide(a, b):
try:
return a / b
except ZeroDivisionError:
return None
---
x, y = 1, 0
result = careful_dvide(x,y)
if reuslt is None:
print('잘못된 입력')
0으로 나누는 경우 결과가 정해져 있지 않으므로 None을 반환하는것이 타당해 보인다.
하지만 함수로 반환한 결과를 if 문 등의 조건문으로 검사할 때 0 값이 문제가 될 수 있다. None 인지 검사하는 대신 실수로 빈 값을 False로 취급하는 검사를 실행할 수 있다.
x, y = 0, 5
resut = careful_divide(x, y)
if not result:
print('질못된 입력') # 이 코드가 실행되는데 사실 이 코드가 실행되면 안된다.
분자가 0이 되면 반환값도 0이 되버린다. if 문으로 None을 검사하려고 했는데 실수로 False를 검사하는 경우도 있다.
해결책은 2가지가 있다.
def careful_divide(a, b):
try:
return True, a / b
except ZeroDivisionError:
return False, None
이 함수를 호출하는 쪽에서 튜플을 언패킹해야한다. 이로 인해 나눗셈 결과를 그냥 검사하지 못하고 항상 튜플에서 상태 부븐을 살펴보게 된다.
success, result = careful_divide(x, y)
if not success:
print('잘못된 입력')
이 코드의 문제는 호출자가 (파이썬에서 사용하지 않을 변수에 붙이는 관례인 밑줄 변수 이름을 사용해서) 튜플의 첫 번쨰 부분을 쉽게 무시할 수 있다는 점이다.
_, result = devide(x,y)
if not result:
print ("Invalid inputs")
이런 실수를 줄일 수 있는 더 나은 방법은 특별한 경우에 결코 None을 반환하지 않는것이다. 대신 Exception을 호출한 쪽으로 발생시켜서 호출 자가 이를 처리하게 한다.
다음 코드는 ZeroDivisionError
가 발생한 경우 이를 ValueError
로 던져서 호출한 쪽에 입력값이 잘못됐음을 알리는 경우다.
def careful_divide(a, b):
try:
return a / b
except ZeroDivisionError as e:
raise ValueError('잘못된 입력')
호출자는 더이상 반환 값에 대한 조건문을 사용하지 않아도 된다. 대신 반환값이 항상 올바르다고 가정하고 try else블록에서 이 값을 즉시 사용할 수있다.
x, y = 5, 2
try:
result = a / b
except ValueError:
print('잘못된 입력')
else:
print('결과는 %.1f 입니다.' % result)
>>>
결과는 2.5 입니다.
즐겁게 읽었습니다. 유용한 정보 감사합니다.