def login(self, input_id, input_pw):
if self.id == input_id and self.pw == input_pw:
print("로그인을 성공하셨습니다.")
return
raise Exception("로그인에 실패했습니다.")
raise는 이런 뜻이에요:❗ "입력한 ID 또는 PW가 틀렸으니까 오류를 발생시켜!"
그리고 지금 이 함수는 더 이상 진행되지 않도록 멈춰!
raise가 없으면 어떻게 될까?raise가 없다면, 로그인에 실패했는데도 프로그램이 조용히 넘어갈 수 있어요.
하지만 우리가 원하는 건 **"틀렸다는 걸 명확하게 알려주기"**죠.
그래서 raise를 써서 오류를 강제로 발생시킵니다.
맞아요. 오류는 프로그램을 멈춰요.
그래서 그걸 잡기 위해 우리가 사용하는 게 바로 👉 try - except
try:
member.login("moon", "moon123") # 로그인 성공
except Exception as e:
print(f"오류 발생: {str(e)}") # 오류 발생 시 실행됨
try: 여기 안에서 오류가 생길 수도 있는 코드를 실행해봐요.raise: 문제가 생기면 예외를 발생시켜요.except: 예외가 발생하면 여기서 오류 메시지를 받아서 출력해줘요.=== 로그인 시도 1 ===
로그인을 성공하셨습니다.
=== 로그인 시도 2 ===
오류 발생: 로그인에 실패했습니다.
print()만 실행됨raise Exception(...) → except가 잡아서 오류 메시지 출력
raise는 "문제 생겼어!"라고 강제로 예외를 발생시키는 도구
try-except는 그 예외를 잡아서 프로그램이 죽지 않게 처리하는 도구
# 로그인 실패 시
raise Exception("로그인에 실패했습니다.")
👇 이건 이렇게 해석할 수 있어요:
⚠️ "비밀번호 틀렸어! 이제부터 오류 처리 코드로 넘어가!"
좋은 지적이에요! raise Exception("...")은 일반적인 예외를 발생시키는 방식이지만, 어떤 종류의 오류인지 명확하지 않기 때문에 실제 프로그램에서는 더 구체적인 예외를 사용하는 것이 좋습니다. NameError, ValueError 외에도 파이썬에는 다양한 내장 예외 클래스가 있습니다.
로그인 실패와 같은 경우에는 보통 다음 예외들 중에서 상황에 따라 골라 사용합니다:
ValueError
입력된 값이 예상 범위나 조건에 맞지 않을 때 사용.
→ 로그인 정보가 잘못되었을 때 적합.
raise ValueError("아이디 또는 비밀번호가 올바르지 않습니다.")
PermissionError
권한이 없을 때 사용.
→ 인증(Authorization) 실패 상황에 적합.
raise PermissionError("로그인에 실패했습니다. 접근 권한이 없습니다.")
AuthenticationError (표준 내장 예외는 아니지만, 사용자 정의로 자주 사용됨)
→ 로그인 같은 인증 실패에 대해 명확하게 표현할 수 있도록 커스텀 예외를 정의해 사용.
class AuthenticationError(Exception):
pass
# 사용 예
raise AuthenticationError("아이디 또는 비밀번호가 틀렸습니다.")
class AuthenticationError(Exception):
pass
class Member:
def __init__(self, id, pw):
self.id = id
self.pw = pw
def login(self, input_id, input_pw):
if self.id == input_id and self.pw == input_pw:
print("로그인을 성공하셨습니다.")
else:
raise AuthenticationError("아이디 또는 비밀번호가 틀렸습니다.")
# 인스턴스 생성
member = Member("moon", "right")
print("=== 로그인 시도 1 ===")
member.login("moon", "right") # 성공
print("\n=== 로그인 시도 2 ===")
member.login("moon", "wrong") # 실패 → AuthenticationError 발생
raise Exception(...)은 너무 일반적이므로 상황에 맞는 예외 (ValueError, PermissionError, 또는 사용자 정의 예외 등)를 사용하세요.ValueError나 PermissionError, 또는 사용자 정의 AuthenticationError가 적합합니다.좋아요! 파이썬에서 자주 쓰이는 기본 내장 예외 종류를 정리해서 간단한 예제와 함께 설명드릴게요. 이걸 이해하면 디버깅이나 예외 처리할 때 훨씬 유용해요!
| 예외 이름 | 언제 발생하나요? | 간단 설명 | 예제 |
|---|---|---|---|
ValueError | 값이 잘못되었을 때 | 형식은 맞지만 값이 이상함 | int("hello") |
TypeError | 타입이 안 맞을 때 | 잘못된 타입 사용 | len(123) |
NameError | 이름이 정의되지 않았을 때 | 존재하지 않는 변수 사용 | print(x) |
IndexError | 리스트 인덱스 범위를 벗어났을 때 | 없는 위치에 접근 | lst[10] |
KeyError | 딕셔너리에 없는 키 접근 | 존재하지 않는 키 | dct["nope"] |
AttributeError | 없는 속성에 접근 | 객체에 없는 메서드/속성 사용 | "hi".append(1) |
ZeroDivisionError | 0으로 나눌 때 | 0으로 나누기 | 5 / 0 |
ImportError / ModuleNotFoundError | 모듈이 없을 때 | 모듈 import 실패 | import notamodule |
PermissionError | 권한이 없을 때 | 파일/디렉토리 접근 실패 등 | 파일 권한 문제 |
FileNotFoundError | 파일이 없을 때 | 존재하지 않는 파일 열기 | open("x.txt") |
ValueErrorint("abc") # 문자열이긴 하지만 숫자가 아님
TypeErrorlen(10) # 숫자에는 len() 못 씀
NameErrorprint(my_var) # my_var가 정의되어 있지 않음
IndexErrorlst = [1, 2, 3]
print(lst[10]) # 인덱스 10은 없음
KeyErrord = {"name": "Tom"}
print(d["age"]) # 'age'라는 키 없음
AttributeErrors = "hello"
s.append("!") # 문자열은 append() 없음
ZeroDivisionError5 / 0
ImportError / ModuleNotFoundErrorimport notamodule
PermissionError# 권한 없는 파일에 쓰기 시도 등
FileNotFoundErroropen("nofile.txt")
| 예외 | 이유 | 예시 |
|---|---|---|
ValueError | 값이 부적절 | int("abc") |
TypeError | 타입이 이상함 | len(10) |
NameError | 이름이 없음 | print(x) |
IndexError | 인덱스 초과 | lst[100] |
KeyError | 키가 없음 | dct["x"] |
AttributeError | 속성 없음 | "hi".append() |
ZeroDivisionError | 0으로 나눔 | 1/0 |
ImportError | 모듈 못 찾음 | import fake |
PermissionError | 권한 없음 | 권한 없는 파일 |
FileNotFoundError | 파일 없음 | open("x.txt") |
좋은 관찰이에요! 😊
하지만 NameError가 더 적합하다고 생각하신 건 약간의 오해일 수 있어요. 지금 상황을 정확히 분석해볼게요.
member.login("moon", "wrong") # 비밀번호 틀림 → raise Exception(...)
input_id와 input_pw는 정상적으로 변수로 넘어온 값입니다.self.id와 self.pw와 다르기 때문에 예외를 일부러 발생시키는 거예요.raise Exception(...)을 어떤 예외로 바꾸면 좋을까를 고민 중이신 거죠?NameError는 부적절한가?
NameError는 "존재하지 않는 변수나 이름"을 사용했을 때 자동으로 발생합니다.
print(abc) # abc라는 변수를 선언하지 않았음 → NameError
✔️ 즉, 변수 자체가 없거나 정의되지 않았을 때 자동으로 생기는 에러지, 값이 틀려서 수동으로 발생시키는 에러가 아닙니다.
TypeError도 부적절한가?
TypeError는 잘못된 자료형(type) 을 사용할 때 발생합니다.
예:
len(123) # 숫자에는 len() 못 씀 → TypeError
"hi" + 3 # 문자열 + 숫자 → TypeError
✔️ 지금 상황에서는 "문자열"과 "문자열"을 비교하고 있으니 자료형 문제도 없습니다.
ValueError가 가장 적절한가?"값의 형식은 맞지만, 내용이 유효하지 않다"는 뜻이기 때문입니다.
→ ✔️ 이럴 때 ValueError가 가장 알맞습니다.
| 에러 | 적절한가? | 이유 |
|---|---|---|
NameError | ❌ | 변수 이름이 없을 때 자동 발생함. 수동 사용 부적절 |
TypeError | ❌ | 자료형(type)이 틀릴 때. 지금은 다 문자열이라 해당 없음 |
ValueError | ✅ | 값의 내용이 잘못됐을 때 사용. 로그인 실패에 적합 |