1 제어 흐름문 개요
Python의 제어 흐름문(Control Flow Statements)은 프로그램의 실행 순서를 제어하는 구문이다. 크게 예외 처리, 반복 제어, 조건문으로 나뉜다.
2 제어 흐름문 분류
2.1 예외 처리 (Exception Handling)
try- 예외 발생 가능 코드 실행except- 예외 처리finally- 항상 실행되는 정리 코드else- 예외 없을 때 실행raise- 예외 발생
2.2 반복 제어 (Loop Control)
break- 반복문 종료continue- 현재 반복 건너뛰기pass- 아무것도 하지 않음
2.3 조건문 (Conditional Statements)
if- 조건 검사elif- 추가 조건else- 기본 경우
2.4 반복문 (Iteration Statements)
for- 시퀀스 순회while- 조건 기반 반복
2.5 함수 제어
return- 함수 종료 및 값 반환yield- 제너레이터 값 생성
3 예외 처리: try-except-finally
3.1 예외 처리의 필요성
프로그램 실행 중 예상치 못한 에러가 발생하면 프로그램이 즉시 중단된다. 예외 처리 구문을 사용하면 에러 발생 시에도 프로그램을 안전하게 제어할 수 있다.
3.1.1 예외 처리 없는 경우
3.1.2 예외 처리 있는 경우
3.2 try-except-finally 구조
3.3 각 블록의 역할
3.3.1 try 블록
예외가 발생할 수 있는 코드를 “시도”한다. 예외 발생 시 즉시 중단되고 해당 예외를 처리하는 except 블록으로 이동한다.
3.3.2 except 블록
특정 예외가 발생하면 실행된다. 예외를 잡아서 처리하여 프로그램 중단을 방지한다.
3.3.2.1 여러 예외 처리
3.3.2.2 예외 객체 활용
3.3.3 finally 블록
예외 발생 여부와 무관하게 항상 실행된다. 주로 리소스 정리(파일 닫기, 연결 종료 등)에 사용된다.
3.3.4 else 블록 (선택적)
try 블록에서 예외가 발생하지 않았을 때만 실행된다.
3.4 실행 흐름
f = open('file.txt', 'r')
try:
data = f.read()
result = process(data) # 예외 발생 가능
except ProcessingError as e:
print(f"처리 실패: {e}")
finally:
f.close() # 예외 발생해도 반드시 실행실행 순서: 1. 파일 열기 (open) 2. try 블록 실행 3. 예외 발생 시 → except 블록 실행 4. 예외 여부 무관 → finally 블록 항상 실행
3.5 실용 예제
3.5.1 파일 처리
def read_config(filename):
config = None
try:
with open(filename, 'r') as f:
config = json.load(f)
except FileNotFoundError:
print(f"설정 파일 {filename}을 찾을 수 없습니다")
config = default_config()
except json.JSONDecodeError:
print("설정 파일 형식이 잘못되었습니다")
config = default_config()
finally:
print("설정 로드 시도 완료")
return config3.5.2 네트워크 요청
import requests
try:
response = requests.get('https://api.example.com/data', timeout=5)
response.raise_for_status()
data = response.json()
except requests.Timeout:
print("요청 시간 초과")
except requests.ConnectionError:
print("연결 실패")
except requests.HTTPError as e:
print(f"HTTP 오류: {e.response.status_code}")
except Exception as e:
print(f"예상치 못한 오류: {e}")
else:
print("데이터 수신 성공")
finally:
print("요청 완료")3.5.3 데이터베이스 트랜잭션
import sqlite3
conn = sqlite3.connect('database.db')
try:
cursor = conn.cursor()
cursor.execute('INSERT INTO users VALUES (?, ?)', (1, 'John'))
cursor.execute('INSERT INTO users VALUES (?, ?)', (2, 'Jane'))
conn.commit()
except sqlite3.IntegrityError:
print("중복된 데이터")
conn.rollback()
except Exception as e:
print(f"오류 발생: {e}")
conn.rollback()
finally:
conn.close()4 반복 제어: break와 continue
4.1 break: 반복문 종료
break는 반복문을 즉시 종료하고 빠져나온다.
4.1.1 실용 예제
4.2 continue: 현재 반복 건너뛰기
continue는 현재 반복만 건너뛰고 다음 반복으로 넘어간다.
4.2.1 실용 예제
4.3 break vs continue 비교
4.4 중첩 반복문에서의 사용
5 기타 제어문
5.1 pass: 빈 블록
아무것도 하지 않는 자리 채우기용 구문이다. 문법적으로 블록이 필요하지만 아직 구현하지 않았을 때 사용한다.
5.2 return: 함수 종료
함수 실행을 종료하고 값을 반환한다.
5.3 raise: 예외 발생
명시적으로 예외를 발생시킨다.
6 예시
6.1 구체적인 예외 처리
6.2 finally보다 with 선호
6.3 조기 반환으로 중첩 줄이기
6.4 Tip: Try statement 사용 시 주의사항
try:
if history_file.exists():
with open(history_file) as f:
history = json.load(f)
if response_times_file.exists():
with open(response_times_file) as f:
response_times = json.load(f)
if messages_file.exists():
with open(messages_file) as f:
messages = json.load(f)
if metrics_file.exists():
with open(metrics_file) as f:
metrics = json.load(f)
except:
pass- 첫번째 문제 except 블록이 pass로 되어 있어 예외의 조건이 너무 추상적이고 광범위하다. 어떤 예외가 발생했는지 알 수 없고, 모든 예외를 무시하기 때문에 디버깅이 어려워진다.
- 두번째 문제는 history.json에서 오류가 나면 나머지 파일(response_times, messages, metrics)도 로드 안 됨. 각 파일마다 try-except 블록을 분리해서 처리하는 것이 좋다.
- 코드 중복
- 해결책: 헬퍼 함수를 만들어 코드 중복을 줄이고, 구체적인 예외를 처리하도록 개선한다.
def _load_json_safe(file_path: Path):
"""JSON 파일을 안전하게 로드"""
if not file_path.exists():
return []
try:
with open(file_path, encoding='utf-8') as f:
return json.load(f)
except (json.JSONDecodeError, IOError) as e:
print(f"⚠️ {file_path.name} 로드 실패: {e}")
return []
def load_persistent_data():
history = _load_json_safe(LOG_DATA_DIR / "history.json")
response_times = _load_json_safe(LOG_DATA_DIR / "response_times.json")
messages = _load_json_safe(LOG_DATA_DIR / "messages.json")
metrics = _load_json_safe(LOG_DATA_DIR / "metrics.json")
return history, response_times, messages, metrics7 요약
| 구문 | 용도 | 선택성 |
|---|---|---|
try |
예외 발생 가능 코드 | 필수 |
except |
예외 처리 | 선택 |
finally |
항상 실행 (정리) | 선택 |
else |
예외 없을 때 실행 | 선택 |
break |
반복문 종료 | - |
continue |
현재 반복 건너뛰기 | - |
pass |
아무것도 안 함 | - |
제어 흐름문은 Python 프로그래밍의 핵심이며, 적절히 사용하면 견고하고 읽기 쉬운 코드를 작성할 수 있다.