파이썬 제어문

Python 제어문은 프로그램의 실행 흐름을 제어하는 핵심 구문으로, 조건부 실행과 반복 실행을 통해 동적이고 효율적인 프로그램을 작성할 수 있게 해줍니다. 주요 제어문으로는 조건문(if, elif, else), 반복문(for, while), 제어 흐름 변경문(break, continue, pass), 예외 처리문(try, except, finally), 그리고 특수한 yield 키워드가 있다.

조건문 (Conditional Statements)

조건문은 주어진 조건이 참(True)인지 거짓(False)인지에 따라 실행 경로를 결정한다.

  • if: 조건문의 시작을 알리며, 조건이 일 경우에만 하위 코드 블록을 실행한다.
  • elif: “else if”의 줄임말로, 이전 if나 elif 조건이 거짓일 때 새로운 조건을 검사합니다. 여러 개를 사용할 수 있다.
  • else: 위의 모든 if, elif 조건이 거짓일 때 마지막으로 실행됩니다. 조건식이 필요 없다.
score = 85

if score >= 90:
    grade = "A"
    print("최우수 학생입니다.")
elif score >= 80:
    grade = "B"
    print("우수 학생입니다.")
else:
    grade = "C"
    print("조금 더 노력해 보세요.")

반복문 (Looping Statements)

반복문은 특정 코드 블록을 여러 번 실행할 때 사용된다.

  • for: 리스트, 튜플, 문자열 등 순회 가능한(iterable) 객체의 각 요소를 하나씩 꺼내 코드 블록을 실행합니다. 반복 횟수가 정해져 있을 때
  • while: 주어진 조건이 참(True)인 동안 코드 블록을 계속해서 반복 실행합니다. 특정 조건이 만족될 때까지 반복해야 할 때 유용하다.
fruits = ["사과", "바나나", "체리"]
for fruit in fruits:
    print(f"현재 과일: {fruit}")

count = 5
while count > 0:
    print(f"카운트다운: {count}")
    count -= 1 # count를 1씩 감소시켜 언젠가 루프가 끝나도록 함

반복문 보조 제어문

반복문의 흐름을 세밀하게 제어하기 위해 사용된다.

  • break: 반복문을 즉시 완전히 중단하고 빠져나온다.
  • continue: 현재 반복을 중단하고 다음 반복으로 바로 넘어간다.
  • pass: 문법적으로는 코드가 필요하지만, 실행할 내용이 없을 때 사용하는 자리 채움 키워드입니다. 아무 동작도 하지 않는다.
for i in range(1, 10):
    if i == 7:
        print("7을 발견하여 반복을 완전히 중단합니다.")
        break  # i가 7이면 for문 전체를 빠져나감
    
    if i % 2 != 0:
        continue # i가 홀수이면 현재 반복을 건너뛰고 다음 숫자로 넘어감
        
    print(f"짝수 발견: {i}")

Try, Except, Finally 구문

try, except, else, finally 구문은 프로그램 실행 중 발생할 수 있는 오류(예외, Exception)를 처리하기 위한 오류 처리 메커니즘입니다. 이 구문을 사용하면 예기치 않은 오류로 인해 프로그램이 중단되는 것을 막고, 오류에 대한 적절한 대응을 하거나 코드를 안전하게 마무리할 수 있다.

  • try: 오류가 발생할 가능성이 있는 코드를 실행하는 블록입니다.
  • except: try 블록에서 오류가 발생했을 때, 이를 처리하기 위한 코드를 실행하는 블록입니다. 특정 오류만 지정해서 잡을 수도 있습니다.
  • finally: try 블록의 성공 여나 오류 발생 여부와 상관없이 항상 마지막에 실행되는 블록입니다. 주로 파일 닫기나 리소스 해제 등 마무리 작업에 사용됩니다.
try:
    # 사용자로부터 문자열을 입력받아 정수로 변환 시도
    num = int(input("나눌 숫자를 입력하세요: "))
    
    # 0으로 나누려고 할 때 에러 발생 가능
    result = 100 / num

# 문자를 입력하는 등 정수로 변환할 수 없을 때 발생하는 에러 처리
except ValueError:
    print("잘못된 입력입니다. 숫자만 입력해주세요.")

# 0으로 나누려고 할 때 발생하는 에러 처리
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다.")

# try 블록이 성공적으로 실행되었을 때만 실행
else:
    print(f"계산 결과는 {result}입니다.")

# 성공하든, 에러가 발생하든 상관없이 항상 실행
finally:
    print("프로그램 실행을 종료합니다.")

with 구문

with 구문은 파일 처리나 데이터베이스 연결 등 자원을 사용하고 난 후, 이를 자동으로 해제하고 정리해주는 역할을 한다. with 블록이 종료될 때(정상적으로 끝나든 오류로 끝나든) 파이썬이 항상 마무리(cleanup) 작업을 수행해 주기 때문에, 코드가 간결해지고 리소스 누수를 방지할 수 있다. with절을 사용하지 않은 경우 try…finally 구문을 사용해, 오류 발생 여부와 상관없이 항상 f.close()를 호출하여 파일을 직접 닫아주어야 합니다. with절을 사용한 경우 with 블록을 벗어나는 순간, 파이썬이 자동으로 파일을 닫아줍니다. 코드가 훨씬 간결하고 안전하다.

# with절을 사용하지 않은 경우
f = open("my_file.txt", "w", encoding="utf-8")
try:
    f.write("파이썬 with절 테스트입니다.")
finally:
    f.close() # 반드시 수동으로 닫아야 

# with절을 사용한 경우
with open("my_file_with.txt", "w", encoding="utf-8") as f:
    f.write("파이썬 with절을 사용하니 코드가 간결합니다.")
    
#  지점에 도달하면 파일 'f' 자동으로 닫힙니다.
print("파일 쓰기가 완료되었고, 파일은 자동으로 닫혔습니다.")

참고: 제너레이터 키워드 yield (조건문이 아님)

yield는 조건문이나 반복문과 같은 제어문이 아니라, 제너레이터(Generator) 함수를 만드는 데 사용되는 특별한 키워드입니다. 제너레이터는 데이터의 스트림을 생성하는 함수로, 모든 값을 메모리에 올리지 않고 필요할 때마다 값을 하나씩 생성하여 자원을 효율적으로 사용하게 해준다.

  • return과의 차이: return은 함수를 완전히 종료시키고 값을 반환하지만, yield는 값을 반환한 뒤 함수의 상태를 일시 정지했다가, 다음 값 요청 시 멈췄던 부분부터 실행을 재개한다.
def count_up_to(max_num):
    """1부터 max_num까지 숫자를 하나씩 생성하는 제너레이터"""
    count = 1
    while count <= max_num:
        yield count  # count 값을 반환하고 여기서 실행을 일시 정지
        count += 1

# 제너레이터 객체 생성
counter = count_up_to(3)

# 필요할 때마다 next()로 값을 하나씩 가져옴
print(next(counter)) # 출력: 1
print(next(counter)) # 출력: 2
print(next(counter)) # 출력: 3

Python 제어문을 사용할 때 가장 중요한 것은 들여쓰기(indentation)를 정확히 맞추는 것 - Python은 중괄호 대신 들여쓰기로 코드 블록을 구분하므로 공백이나 탭이 일치하지 않으면 IndentationError가 발생한다. while문 사용 시에는 반드시 루프 내에서 조건을 변화시키는 코드를 포함해야 무한 루프를 방지할 수 있으며, for문에서 리스트를 순회하면서 동시에 리스트를 수정하면 예상치 못한 결과가 나올 수 있으므로 주의해야 한다. 또한 조건문에서 =(할당)과 ==(비교)를 혼동하지 않도록 주의하고, break와 continue는 반복문 내에서만 사용할 수 있다는 점을 기억해야 한다.