예외처리와 모듈 — 안전하고 탄탄한 프로그램 설계
사용자가 문자를 입력하거나 파일이 지워져도 멈추지 않는 튼튼한 프로그램(예외처리)을 만듭니다.
그리고 방대해진 코드를 기능별 파일로 분리하는 모듈(Module) 기법으로 실무형 아키텍처를 완성합니다.
학습 목표
- 프로그램이 비정상 종료되는 '오류' 상황을 방어하는
try-except구문을 익힙니다. ValueError,FileNotFoundError등 특정 오류를 콕 집어서 해결합니다.raise를 이용해 '거래금액은 음수가 될 수 없다' 같은 회계 업무 규칙을 강제합니다.- 직접 만든 함수들을
.py파일별로 쪼개고,import로 조립(모듈화)하여 거대한 프로그램을 설계합니다.
오류(Error)로 인한 프로그램 중단
우리가 지금까지 만든 프로그램은 사용자가 완벽하게 데이터를 입력한다고 가정했습니다. 하지만 실무에서는 반드시 예기치 못한 입력이나 상황이 발생합니다.
print("프로그램 시작") number = int(input("거래금액: ")) # 사용자가 'abc'라고 입력한다면? print("입력금액:", number)
프로그램 시작
거래금액: abc
ValueError: invalid literal for int() with base 10: 'abc'
try와 except (방어막 치기)
에러가 날 것 같은 위험한 코드는 try라는 방어막(블록) 안에 넣습니다.
에러가 발생하면 프로그램이 터지지 않고 except 블록으로 부드럽게 이동합니다.
try: number = int(input("숫자 입력: ")) print(number) except: print("숫자를 입력해야 합니다! (프로그램 안 꺼짐)")
특정 오류 처리 (ValueError, FileNotFoundError)
단순히 except:만 쓰면 모든 오류를 뭉뚱그려 잡기 때문에 디버깅이 힘들어집니다.
어떤 에러가 났는지 정확하게 명시하는 것이 실무의 기본입니다.
try: amt = int(input("금액: ")) except ValueError: print("문자가 입력되었습니다.")
try: with open("data.csv", "r") as f: pass except FileNotFoundError: print("파일이 없습니다. 새로 생성합니다.")
여러 종류의 오류 동시에 잡기
하나의 try 안에서 다양한 오류를 각각 다르게 처리할 수 있습니다.
def divide_numbers(): try: a = int(input("첫 번째 숫자: ")) # ValueError 위험구간 b = int(input("두 번째 숫자: ")) result = a / b # ZeroDivisionError 위험구간 print("결과:", result) except ValueError: print("숫자만 입력해야 합니다.") except ZeroDivisionError: print("0으로 나눌 수 없습니다.")
전체 예외처리 구조 (else, finally)
else는 에러가 안 났을 때만, finally는 에러가 났든 안 났든 무조건 실행되는 블록입니다.
try: number = int(input("숫자: ")) except ValueError: print("오류: 숫자가 아닙니다.") else: print(f"성공! 입력한 숫자: {number}") finally: print("이 문장은 무조건 마지막에 출력됩니다.")
업무 규칙 검증하기 (raise)
파이썬 문법적으로는 에러가 아니더라도, 회계 로직상 잘못된 값(예: 거래금액이 마이너스)이 들어오면 프로그래머가 강제로 에러를 발생시킬 수 있습니다. 이를 raise라고 합니다.
def check_amount(amount): if amount <= 0: # 에러를 강제로 발생시키고 메시지를 달아줌 raise ValueError("거래금액은 0보다 커야 합니다.") return True try: check_amount(-5000) except ValueError as e: print("업무규칙 위반:", e) # 우리가 적은 메시지가 e에 담겨 출력됨
함수와 예외처리의 결합 (무적의 입력창)
실무 프로그램에서 사용자로부터 값을 받을 때 가장 많이 쓰는 '제대로 된 값이 들어올 때까지 무한반복으로 가둬두기' 패턴입니다.
def input_amount(): while True: try: amount = int(input("거래금액 입력: ")) if amount <= 0: print("금액은 0보다 커야 합니다. 다시 입력하세요.") continue # 다시 위로 올라가서 입력받음 return amount # 완벽한 숫자일 때만 return 하면서 while문을 탈출! except ValueError: print("숫자만 입력해 주세요.") # 메인 코드에서는 고민할 필요 없이 함수만 호출하면 됩니다. safe_amount = input_amount()
모듈(Module)과 import
지금까지 배운 것을 바탕으로 프로그램이 커지면, 코드가 수백 줄을 넘어갑니다.
이럴 때는 파이썬 코드를 기능별로 여러 개의 `.py` 파일로 쪼개고 조립합니다. 이때 사용하는 것이 import 입니다.
def add(a, b): return a + b def vat(amt): return amt * 0.1
import calculator # calculator.py 안의 함수를 가져다 씁니다. result = calculator.add(10, 20) tax = calculator.vat(1000)
import calculator as calc
print(calc.vat(1000))
# 파일 이름 안 붙이고 함수만 쏙 빼오기
from calculator import vat
print(vat(1000))
프로그램 파일 분리 (실무 구조)
실제 회계 업무 프로그램을 만든다면, 하나의 폴더 안에서 다음과 같이 역할을 분리(모듈화)합니다.
├── main.py # 사용자 메뉴(while), 흐름 제어, 타 모듈 import
├── customer.py # 거래처 등록, 검색 함수
├── calculator.py # 합계, 평균, 부가세 로직
└── file_manager.py # CSV/JSON 저장 및 로드 로직 (try-except 포함)
이 구조로 짜면 파일 저장이 안 될 땐 file_manager.py만 고치면 되고, 세법이 바뀌어 세율을 고쳐야 할 땐 calculator.py만 수정하면 됩니다. 유지보수성이 극대화됩니다.
8단계 실습 — 안전한 모듈화 프로그램 만들기
7단계의 거래처 관리 프로그램 코드를 각 기능별 파일(main.py, file_manager.py, customer.py 등)로 쪼개서 구성해보는 것이 이번 단계의 최종 과제입니다.
- 안정성 1:
try-except를 이용해 사용자가 숫자가 아닌 값을 넣어도 절대 꺼지지 않게 하세요. - 안정성 2:
raise ValueError를 이용해 음수 금액 입력 시 에러를 던지고 다시 입력받게 하세요. - 모듈화: 저장/불러오기 기능은
file_manager.py로 분리하고,main.py에서import file_manager를 해오세요.
Phase 1 (기초 1~8단계) 총정리 및 다음 단계 예고
여기까지 무사히 오신 것을 축하합니다! 🎉 파이썬의 가장 중요한 뼈대 문법을 모두 마쳤습니다.
9단계부터는 회계사 실무와 직결되는 엑셀 뜯어먹기에 돌입합니다.
파이썬이 엑셀 파일을 읽고(Read), 셀 데이터를 조작하고(Modify), 서식을 입혀서(Format), 합계/부가세 계산을 마친 후 새로운 엑셀 보고서를 자동으로 뽑아내는(Save) 마법 같은 일들을 실습하게 됩니다. 진짜 자동화의 세계로 진입합니다!