오늘은 오류를 피하는 것이 아니라 관리하는 법을 배웠다

기초와 중급 초반까지는 코드가 정상적으로 돌아가는 경우를 중심으로 공부했다. 그런데 오늘은 나누기에서 0이 들어오거나, 자료형이 맞지 않는 상황처럼 실제로 충분히 발생할 수 있는 오류를 어떻게 처리할지 배웠다.

처음엔 에러가 나면 그냥 틀린 코드라고만 생각했는데, 예외처리는 “틀릴 수 있는 상황을 미리 예상하고 흐름을 관리하는 것”이라는 점에서 훨씬 실전적인 내용이었다.

중급 1일차부터 3일차까지는 클래스, 생성자, 상속처럼 코드를 더 구조적으로 만드는 쪽을 배웠다면, 오늘은 그 구조가 실제 실행 중 흔들릴 때 어떻게 대응할지를 보는 날이었다. 그래서 오늘 내용은 문법 하나를 더 외우는 것이 아니라, 프로그램을 좀 더 현실적으로 바라보게 만드는 단계라고 느껴졌다.

1. 예외처리는 “실패할 수 있음”을 인정하는 구조다

코드를 처음 배울 때는 보통 정상 입력만 생각하게 된다. 하지만 실제 프로그램은 그렇지 않다.

  • 숫자 대신 문자열이 들어올 수도 있고
  • 나누기에서 0이 들어올 수도 있고
  • 파일이 없을 수도 있고
  • 사용자가 예상과 다르게 입력할 수도 있다

즉, 프로그램은 언제든 실패할 수 있다.

예외처리는 바로 이 지점을 다룬다. 문제가 생기지 않기를 기대하는 대신, 문제가 생겨도 흐름을 제어할 수 있도록 준비하는 것이다.

이 관점이 생기면 에러는 단순한 “실수 결과”가 아니라, 코드 안에서 관리해야 하는 상황으로 보이기 시작한다.

2. try-except는 프로그램이 멈추지 않게 해준다

실습 코드에서는 아래처럼 예외를 처리했다.

def new_div(a, b):
    try:
        result = a / b
        print("Result :", result)
    except ZeroDivisionError:
        print("Error : Division by zero")
    except TypeError:
        print("Error : Type Error")

이 코드를 보면 try 안에서는 정상 흐름을 실행하고, 문제가 생기면 except에서 해당 상황을 따로 처리한다. 예전 같으면 그냥 프로그램이 멈췄을 상황을, 이제는 예상 가능한 문제로 받아들이게 된다.

ZeroDivisionError, TypeError처럼 에러 종류가 다르다는 점도 중요했다. 같은 오류처럼 보여도 원인이 다르면 대응 방식도 달라진다.

즉, try-except는 “오류가 절대 생기지 않게 하는 기술”이 아니라, “오류가 생겼을 때 프로그램이 어떤 반응을 할지 정하는 기술”이라고 이해하는 편이 맞다.

3. tryexcept는 역할이 분명히 다르다

처음 보면 try-except도 그냥 조건문처럼 보일 수 있다. 하지만 실제 역할은 다르다.

try

  • 우선 정상적으로 실행해 보고 싶은 코드
  • 문제가 없으면 그대로 진행되는 영역

except

  • 실행 중 예외가 발생했을 때만 동작하는 영역
  • 발생한 문제에 맞게 대응하는 곳

예를 들어:

try:
    result = a / b
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다.")

이 구조는 “0인지 먼저 검사한다”라기보다, “일단 실행해 보고 0으로 나누는 문제가 실제 발생하면 처리한다”는 흐름이다.

그래서 iftry-except는 비슷해 보여도 완전히 같은 역할이 아니다.

  • if: 조건을 미리 검사한다
  • try-except: 실행 중 발생한 문제를 처리한다

이 차이를 이해해야 예외처리를 억지로 조건문처럼 쓰지 않게 된다.

4. 예외 종류를 구분하는 이유가 중요했다

오늘 실습에서 인상적이었던 점은 오류를 한 덩어리로 보지 않았다는 점이다.

except ZeroDivisionError:
    print("Error : Division by zero")
except TypeError:
    print("Error : Type Error")

이렇게 나눈 이유는 분명하다.

  • ZeroDivisionError는 수학적으로 잘못된 연산 상황이고
  • TypeError는 자료형이 맞지 않는 상황이다

둘 다 계산이 실패한다는 공통점은 있지만, 실패 원인은 다르다. 그래서 사용자에게 보여 줄 메시지도 달라질 수 있고, 나중에 복구 방식도 달라질 수 있다.

즉, 예외처리에서 중요한 건 단순히 “에러를 잡는다”가 아니라, “어떤 종류의 문제인지 구분해서 다룬다”는 감각이다.

이 지점이 있어야 프로그램이 거칠지 않고, 조금 더 실전적인 코드처럼 보이기 시작한다.

5. 상속 예제와 연결해 보니 더 이해가 쉬웠다

상속 예제와도 연결되는 코드가 있었다.

class SafeFourCal(FourCal):
    def div(self):
        if self.second == 0:
            return 0
        else:
            return self.first / self.second

이 코드는 예외를 직접 잡는 방식은 아니지만, 위험한 입력을 미리 걸러서 안전하게 처리한다는 점에서 같은 맥락으로 이해할 수 있었다. 결국 중요한 건 “문제가 생길 수 있는 지점”을 코드에 반영하는 것이다.

여기서 중요한 점은 SafeFourCal이 부모 클래스 FourCal의 구조를 그대로 활용하면서 div()만 안전하게 바꿨다는 것이다. 즉, day3에서 배운 상속이 day4에서 “방어적인 기능 확장”으로 연결된 셈이다.

이 흐름을 보면 공부가 따로 떨어져 있지 않다는 게 보인다.

  • day2에서는 생성자로 객체 상태를 정리했고
  • day3에서는 상속으로 기능을 확장했고
  • day4에서는 그 확장된 기능을 더 안전하게 만들었다

즉, 오늘 내용은 예외처리 자체도 중요하지만, 기존 클래스 구조 안에 안전장치를 넣는 시각을 배우는 날이기도 했다.

6. 예외를 꼭 except로만 처리하는 것은 아니다

오늘 배운 내용을 정리하면서 느낀 건, 예외처리는 한 가지 방식만 있는 게 아니라는 점이다.

예를 들면:

  • try-except로 실제 예외를 잡을 수 있고
  • if로 위험한 조건을 미리 막을 수도 있다

SafeFourCal은 두 번째 방식에 가깝다.

if self.second == 0:
    return 0

이렇게 하면 예외가 터진 뒤 처리하는 것이 아니라, 예외가 생길 상황 자체를 미리 막는다.

그래서 오늘은 “예외처리 = 무조건 try-except”라고 외우기보다, “문제가 생길 수 있는 지점을 어떻게 다룰 것인가”로 생각하는 편이 더 정확하다고 느꼈다.

7. 모듈 분리는 코드를 나누는 첫 연습이었다

오늘 함께 본 파일 중에는 calc.py도 있었다.

def plus(a, b):
    return a + b

def minus(a, b):
    return a - b

def mul(a, b):
    return a * b

def div(a, b):
    return a / b

이 파일을 보면서 모듈은 “기능별로 분리해둔 Python 파일”이라는 감각이 조금 생겼다. 아직 큰 프로젝트를 하는 단계는 아니지만, 연산 기능을 따로 모아두면 메인 코드가 훨씬 읽기 쉬워진다.

기초에서는 함수 하나하나를 배우는 느낌이었다면, 오늘은 그런 함수들을 파일 단위로 정리하는 감각까지 조금씩 연결됐다.

calc.py 같은 모듈은 단순해 보여도 의미가 크다. 코드가 길어질수록 모든 함수를 한 파일에 몰아넣으면 읽기 어렵고, 나중에 수정할 때도 불편해진다. 하지만 계산 관련 함수만 따로 빼 두면 역할이 분명해진다.

즉, 모듈은 “파일을 늘리는 것”이 아니라 “역할을 나누는 것”이다.

8. 모듈을 나누면 읽기와 재사용이 쉬워진다

모듈 분리가 중요한 이유는 아래처럼 정리할 수 있다.

  • 메인 코드가 짧아진다
  • 기능별 책임이 분명해진다
  • 같은 함수를 다른 파일에서도 재사용할 수 있다
  • 수정할 위치를 찾기 쉬워진다

예를 들어 계산 관련 함수가 여러 곳에서 필요하다면, calc.py 하나만 잘 만들어 두고 불러다 쓰면 된다. 그러면 계산 로직을 한 군데에서 관리할 수 있다.

이 감각은 이후에 프로젝트가 커질수록 더 중요해진다.

  • 회원 관련 기능은 회원 모듈로
  • 파일 처리 기능은 파일 모듈로
  • 계산 기능은 계산 모듈로

이렇게 나누기 시작하면 코드가 훨씬 덜 엉킨다.

9. 오늘은 “잘 돌아가는 코드”에서 “관리되는 코드”로 넘어가는 느낌이었다

오늘 내용은 겉으로 보면 두 가지다.

  • 예외처리
  • 모듈 분리

하지만 둘을 같이 보면 공통점이 있다. 둘 다 코드를 더 잘 관리하기 위한 도구라는 점이다.

예외처리는 실행 중 발생할 수 있는 문제를 관리하는 방법이고, 모듈 분리는 커지는 코드를 역할별로 관리하는 방법이다.

그래서 오늘은 단순히 문법 두 개를 배운 날이 아니라, 프로그램을 더 오래 버틸 수 있게 만드는 방향으로 한 걸음 간 날처럼 느껴졌다.

기초 단계에서는 “일단 되게 만드는 것”이 중요했다면, 중급에서는 “문제가 생겨도 덜 무너지고, 구조도 덜 복잡하게 만드는 것”이 중요해진다. 오늘이 바로 그 전환점에 가까웠다.

오늘 헷갈렸던 점

예외처리는 처음 보면 흐름이 일반 조건문과 달라서 조금 헷갈린다. if는 조건을 검사하는 것이고, try-except는 실제 실행 중 생긴 문제를 처리하는 구조라는 점을 구분해야 한다.

또 모듈 분리는 단순히 파일을 쪼개는 게 아니라, 어떤 기능을 어느 파일에 둘지 정리하는 습관과 연결된다는 점도 새로웠다.

오늘의 실수 포인트

  • 예외처리는 코드가 실패할 수 있다는 전제에서 출발한다는 점을 놓치면 안 된다.
  • iftry-except는 비슷해 보여도 역할이 다르다.
  • 모든 오류를 한 가지 방식으로 뭉뚱그려 처리하면 원인 파악이 어려워진다.
  • SafeFourCal처럼 예외 상황을 미리 막는 방식도 중요한 대응 방법이다.
  • 모듈은 파일 개수를 늘리는 것이 아니라, 역할을 나누고 재사용성을 높이는 구조다.

즉, 오늘 내용은 개별 문법보다 “어떻게 더 안정적이고 정리된 코드를 만들 것인가”라는 관점으로 기억하는 편이 좋다.

복습용으로 남기는 질문

1. try-except는 언제 필요한가?

코드 실행 중 오류가 생길 가능성이 있을 때 필요하다. 예외가 발생해도 프로그램이 바로 멈추지 않고, 정해 둔 방식으로 대응하게 만들 수 있다.

2. ZeroDivisionErrorTypeError는 어떤 차이가 있는가?

ZeroDivisionError는 0으로 나누는 잘못된 연산에서 생기고, TypeError는 자료형이 맞지 않아 연산이나 함수 사용이 불가능할 때 생긴다.

3. iftry-except는 어떤 점에서 다른가?

if는 조건을 미리 검사하는 방식이고, try-except는 실제 실행하다가 발생한 예외를 처리하는 방식이다. 둘 다 안전장치지만 쓰이는 시점이 다르다.

4. SafeFourCal은 왜 예외처리와 연결해서 이해할 수 있는가?

0으로 나누는 위험한 상황을 미리 검사해 막기 때문이다. 예외를 직접 잡지는 않지만, 문제가 생길 지점을 코드에 반영한다는 점에서 같은 맥락이다.

5. calc.py처럼 파일을 분리하는 이유는 무엇인가?

기능별로 코드를 나눠 메인 코드가 덜 복잡해지고, 관련 기능을 한곳에서 관리하고 재사용하기 쉬워지기 때문이다.

6. 모듈 분리는 코드 구조에 어떤 장점을 주는가?

역할이 분명해지고, 읽기 쉬워지며, 재사용성과 유지보수성이 좋아진다. 프로젝트가 커질수록 이런 구조 분리가 더 중요해진다.

한 줄 정리

오늘은 Python 코드가 실패할 수도 있다는 전제를 받아들이고, 그 실패를 관리하는 예외처리와 기능을 역할별로 나누는 모듈 분리를 통해 코드를 한층 더 실전적으로 바라보게 된 날이었다.

Community

Comments

0 comments

Comments appear immediately. Use report if something needs review.

No comments yet.