본문으로 바로가기
제품데스크톱 도구TASTECAD도면 확인TASTEFILES파일 관리TASTEFTP파일 전송TASTESSH원격 작업공간TASTEZIP압축과 해제개발 도구TASTECODERust 통합 개발 환경TASTESTUDIO통합 개발·테스트 환경TASTEETL데이터 통합(ETL)서버TASTEREMOTE원격 데스크톱 서버TASTEGEO공간정보 서버TASTEMAIL메일 작업공간시작하기다운로드문서구매모든 제품
마켓플레이스
소식
개발소식오늘의 개발 소식개발 문서프로그래밍 언어RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart프런트엔드 프레임워크Next.jsReactVue.js · NuxtSvelteKitAngular서버 프레임워크Spring BootDjangoFastAPIASP.NET CoreNestJS · Express앱 · 데스크톱 프레임워크TauriFlutterReact NativeElectron알고리즘알고리즘 기초알고리즘 핵심알고리즘 심화실무 알고리즘
커뮤니티프로젝트개발 로그프롬프트AI 도구 이슈쇼케이스커뮤니티 안내
협업기술 전수홈페이지 구축데스크톱 앱 구축릴리스·결제 파이프라인판매 파트너문의
서비스원격 데스크톱설치 패키지 커스텀
TASTEDEV
제품

데스크톱 도구

TASTECAD복잡한 도면을 가볍게 열다TASTEFILES필요한 파일만, 가장 빠르게TASTEFTP파일이 오가는 가장 단정한 길TASTESSH서버와 나 사이, 더 단단한 연결TASTEZIP더 빠르게 묶고, 더 안전하게 풀다

개발 도구

TASTECODERust 앱을 편집 · 빌드 · 디버깅 · 테스트까지 한 창에서TASTESTUDIO편집부터 원격 테스트와 승인 기반 AI 수정까지TASTEETL값을 보며 데이터를 옮깁니다

서버

TASTEREMOTE우리 회사 서버로 운영하는 원격 데스크톱TASTEGEOGeoServer 호환 공간정보 서버를 Rust로 다시 세웁니다TASTEMAIL메일의 주도권을 다시 내 손에

시작하기

다운로드모든 제품 최신 판문서제품 사용법구매구독 · 영구 라이선스모든 제품모든 제품 한눈에
모든 제품
마켓플레이스소식
개발

소식

오늘의 개발 소식언어 · 프레임워크 · GitHub · AI 공식 발표개발 문서언어 · 프레임워크 · 알고리즘 안내서

프로그래밍 언어

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

프레임워크

프런트엔드 프레임워크Next.jsReactVue.js · NuxtSvelteKitAngular
서버 프레임워크Spring BootDjangoFastAPIASP.NET CoreNestJS · Express
앱 · 데스크톱 프레임워크TauriFlutterReact NativeElectron

알고리즘

알고리즘 기초복잡도 분석 · 정렬 · 탐색 · 기본 자료구조 · 트리와 힙알고리즘 핵심그래프 탐색 · 최단 경로와 최소 신장 트리 · 동적 계획법 · 탐욕 알고리즘 · 분할 정복 · 백트래킹알고리즘 심화문자열 알고리즘 · 수학과 정수론 · 비트 연산 · 구간 트리 · 유니온 파인드실무 알고리즘코딩 면접 풀이 전략 · LRU 캐시 · 레이트 리미터 · 일관된 해시
개발 문서 전체 보기
커뮤니티
프로젝트빌더와 작업 발견개발 로그결정과 시행착오프롬프트재사용 가능한 지시AI 도구 이슈Claude · Codex · Gemini 문제와 우회법쇼케이스완성된 결과커뮤니티 안내공개하고 함께 만드는 방식
협업
기술 전수Rust·egui 네이티브 앱 만들기홈페이지 구축10개 언어, 계정, 문서·다운로드데스크톱 앱 구축Rust·egui, WebView 없이릴리스·결제 파이프라인서명 · MSI·deb·rpm·AppImage · 해시판매 파트너소개하고 결제액의 30% 받기문의구축 · 제휴 · 투자 문의
서비스
원격 데스크톱브라우저로 내 컴퓨터에 접속설치 패키지 커스텀필요한 기능만, 설정은 미리
구매
KO
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
로그인
로그인
TASTEDEV

작은 도구부터, 더 좋은 개발까지.

support@tastedev.netTASTEDEV 후원하기
제품제품군구매문서다운로드마켓플레이스고객 지원
커뮤니티프로젝트개발 로그프롬프트AI 도구 이슈쇼케이스
정책개인정보처리방침이용약관구독 약관환불 정책커뮤니티 운영 정책
계정로그인가입하기
방문자
오늘
012345678901234567890123456789012345678901234567890123456789
어제
012345678901234567890123456789012345678901234567890123456789
누적 조회
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
상호
지엑스소프트
대표자
최영구
사업자등록번호
853-44-00368
주소
인천광역시 미추홀구 경인로 351 9층 V24
전화
+82-10-4404-1523
이메일
whitecalvin@tastedev.net
개인정보 보호책임자
최영구

© 2026 TASTEDEV제품 정보는 현재 검증된 개발 소스를 기준으로 합니다.출시·고도화 중

Python 문서
Python
시작하기기본 문법타입과 데이터모듈과 패키지오류 처리와 테스트핵심 개념
토론

Python 안내서 · 5/6

오류 처리와 테스트

Python은 오류를 반환값이 아니라 예외(exception)로 알립니다. 이 장에서는 예외를 잡고 다루는 try 문의 네 부분, 직접 예외를 일으키고 만드는 법, 자원을 안전하게 정리하는 컨텍스트 관리자, 그리고 pytest와 unittest로 코드를 검증하는 방법을 살펴봅니다.

예외와 try 문

예외가 일어나면 실행이 그 자리에서 멈추고, 이를 처리하는 except를 찾을 때까지 호출한 쪽으로 거슬러 올라갑니다. 끝까지 처리되지 않으면 프로그램이 트레이스백(traceback)을 출력하고 종료합니다. try 문은 네 부분으로 이루어집니다.

절실행되는 때
try예외가 날 수 있는 코드를 실행합니다
except지정한 종류의 예외가 났을 때
else예외 없이 try가 끝났을 때
finally예외 여부와 상관없이 항상 마지막에
def read_number(path: str) -> int:
    try:
        f = open(path, encoding="utf-8")
    except FileNotFoundError:
        print(f"{path} 파일이 없습니다")
        return 0
    else:
        try:
            return int(f.read().strip())
        except ValueError as e:
            print(f"숫자가 아닙니다: {e}")
            return 0
        finally:
            f.close()   # 성공하든 실패하든 파일을 닫습니다

except에는 처리할 수 있는 구체적인 예외만 적습니다. 아무 예외나 잡는 맨 except:나 except Exception:을 남발하면 진짜 버그까지 숨겨 버립니다. 여러 예외를 함께 처리할 때는 except (KeyError, IndexError):처럼 튜플로 묶습니다.

예외 일으키기와 사용자 정의 예외

잘못된 입력이나 상태를 만나면 raise로 예외를 일으킵니다. 도메인에 맞는 예외가 필요하면 Exception을 상속해 직접 만듭니다. 기반 예외 클래스를 하나 두고 세부 예외를 그 아래에 두면, 호출하는 쪽이 원하는 수준에서 골라 잡을 수 있습니다.

class PaymentError(Exception):
    """결제 관련 오류의 기반 클래스"""


class InsufficientFunds(PaymentError):
    def __init__(self, needed: int, available: int) -> None:
        super().__init__(f"{needed}원이 필요하지만 {available}원뿐입니다")
        self.needed = needed
        self.available = available


def pay(balance: int, amount: int) -> int:
    if amount <= 0:
        raise ValueError("amount must be positive")
    if amount > balance:
        raise InsufficientFunds(amount, balance)
    return balance - amount


try:
    pay(1000, 5000)
except PaymentError as e:
    print("결제 실패:", e)

다른 예외를 잡은 뒤 더 의미 있는 예외로 바꿔 던질 때는 raise NewError(...) from e를 씁니다. 원래 원인이 트레이스백에 함께 남아 디버깅이 쉬워집니다.

컨텍스트 관리자와 with 문

파일, 네트워크 연결, 잠금처럼 쓰고 나면 반드시 정리해야 하는 자원은 with 문으로 다룹니다. 블록을 벗어날 때 예외가 났더라도 자원이 자동으로 정리되므로 try/finally를 직접 쓰는 것보다 짧고 안전합니다. 직접 만들 때는 contextlib.contextmanager 데코레이터가 간편합니다.

import time
from contextlib import contextmanager

with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("hello\n")
# 여기서 파일은 이미 닫혀 있습니다


@contextmanager
def timer(label: str):
    start = time.perf_counter()
    try:
        yield
    finally:
        elapsed = time.perf_counter() - start
        print(f"{label}: {elapsed:.3f}초")


with timer("합계 계산"):
    total = sum(range(1_000_000))

pytest로 테스트하기

pytest는 Python에서 가장 널리 쓰이는 테스트 도구입니다. test_로 시작하는 파일과 함수를 자동으로 찾아 실행하며, 특별한 단언 메서드 없이 평범한 assert만 쓰면 실패했을 때 값을 자세히 보여 줍니다.

# tests/test_pay.py
import pytest

from payments import InsufficientFunds, pay


def test_pay_reduces_balance():
    assert pay(1000, 300) == 700


def test_pay_rejects_overdraft():
    with pytest.raises(InsufficientFunds):
        pay(100, 500)


@pytest.mark.parametrize("amount", [0, -10])
def test_pay_rejects_non_positive(amount):
    with pytest.raises(ValueError, match="positive"):
        pay(1000, amount)


def test_writes_file(tmp_path):
    target = tmp_path / "out.txt"   # 테스트마다 새로 만드는 임시 폴더
    target.write_text("ok", encoding="utf-8")
    assert target.read_text(encoding="utf-8") == "ok"
python -m pip install pytest
pytest            # 모든 테스트 실행
pytest -k overdraft -v   # 이름에 overdraft 가 들어간 테스트만 자세히

tmp_path처럼 테스트 함수의 매개변수 이름으로 준비물을 받는 기능을 픽스처(fixture)라고 합니다. @pytest.fixture로 직접 만들 수도 있습니다.

unittest

표준 라이브러리에는 unittest도 들어 있어 추가 설치 없이 쓸 수 있습니다. TestCase를 상속한 클래스에 test_로 시작하는 메서드를 두고 assertEqual 같은 메서드로 검사합니다. pytest는 unittest 형식의 테스트도 그대로 실행합니다.

import unittest

from payments import pay


class PayTest(unittest.TestCase):
    def test_pay(self):
        self.assertEqual(pay(1000, 300), 700)

    def test_negative(self):
        with self.assertRaises(ValueError):
            pay(1000, -1)


if __name__ == "__main__":
    unittest.main()

정리

  • try/except/else/finally로 예외를 다루고, 처리할 수 있는 구체적인 예외만 잡습니다.
  • raise로 예외를 일으키고, Exception을 상속해 도메인 예외를 만들며, 원인은 from으로 잇습니다.
  • 정리가 필요한 자원은 with 문과 컨텍스트 관리자로 다룹니다.
  • 테스트는 pytest의 assert, pytest.raises, 픽스처로 간결하게 쓰고, 표준 unittest도 함께 쓸 수 있습니다.
이 장에 대해 질문이 있나요?
이전 장모듈과 패키지다음 장핵심 개념

댓글 0개

인기 댓글순최신순

로그인 · 로그인하면 댓글을 남길 수 있습니다.