본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] 내부 함수(Nested Function)의 이해와 활용 : 캡슐화와 클로저의 시작

by Papa Martino V 2026. 2. 14.
728x90

내부 함수(Nested Function)
내부 함수(Nested Function)

함수 안의 함수, 단순한 중첩을 넘어 데이터 은닉과 고급 프로그래밍 기법으로 가는 관문


1. 개요: 함수 안에 또 다른 세계를 만들다

파이썬은 '일급 객체(First-class Object)'라는 철학을 바탕으로 함수를 매우 유연하게 다룹니다. 그 정점 중 하나가 바로 내부 함수(Nested Function)입니다. 내부 함수란 말 그대로 정의된 함수(Outer function)의 본문 내부에 위치한 또 다른 함수(Inner function)를 의미합니다. 단순히 코드를 겹쳐 쓰는 것이 아니라, 외부에서는 접근할 수 없는 '나만의 작은 도구'를 만들거나, 상태를 유지하는 '클로저(Closure)'를 생성하는 등 파이썬스러운(Pythonic) 코드를 작성하기 위한 필수적인 개념입니다.

2. 왜 내부 함수를 사용하는가? (핵심 가치와 장점)

내부 함수를 사용하는 이유는 크게 세 가지로 요약할 수 있습니다.

  • 캡슐화(Encapsulation)와 데이터 은닉: 특정 함수 내에서만 필요한 로직을 내부에 숨김으로써 전역 네임스페이스를 보호하고, 외부로부터의 직접적인 접근을 차단합니다.
  • 코드 재사용성 향상: 외부 함수의 인자나 변수를 그대로 활용하면서 반복되는 작업을 처리하는 보조 도구(Helper function)로 유용합니다.
  • 클로저(Closure) 구현: 외부 함수의 실행이 종료된 후에도 그 상태를 기억하고 유지하는 고급 프로그래밍 패턴을 가능하게 합니다.

3. 내부 함수와 일반 함수의 비교

내부 함수가 일반적인 독립 함수와 어떻게 다른지 아래 표를 통해 비교해 보겠습니다.

비교 항목 일반 독립 함수 (Top-level) 내부 함수 (Nested)
정의 위치 모듈 또는 클래스 최상위 다른 함수의 내부 본문
접근성 (Scope) 모듈 어디서나 호출 가능 정의된 외부 함수 내에서만 기본 호출 가능
데이터 접근 매개변수 및 전역 변수 매개변수 + 전역 변수 + 외부 함수의 지역 변수
주요 목적 범용적인 기능 수행 특정 로직의 캡슐화 및 클로저 생성
생성 시점 모듈 로드 시 외부 함수가 호출될 때마다 새롭게 생성

4. 실전 예제: 데이터 은닉과 캡슐화

가장 기본적인 내부 함수의 형태를 통해 어떻게 외부로부터 로직을 보호하는지 확인해 보겠습니다.

[Sample Example] 연산 도우미 내부 함수

def power_calculator(base, exponent):
    """지수 연산을 수행하며 내부 로직을 숨깁니다."""
    
    # 내부 함수 정의
    def validate_input(val):
        # 외부 함수 내에서만 쓰이는 검증 로직
        return isinstance(val, (int, float))

    if not validate_input(base) or not validate_input(exponent):
        raise ValueError("숫자만 입력 가능합니다.")
    
    return base ** exponent

# 사용 예시
print(power_calculator(2, 3))  # 결과: 8
# validate_input(2)  # NameError 발생 (외부 호출 불가능)

5. 중첩 함수의 꽃: 클로저(Closure) 맛보기

내부 함수가 외부 함수의 변수를 기억하고 반환될 때, 이를 클로저라고 부릅니다. 이는 상태를 유지하는 작은 객체처럼 동작합니다.

def multiplier(n):
    """특정 값을 곱해주는 함수를 생성하는 클로저"""
    def multiply(x):
        return x * n  # 외부 함수의 n을 기억함
    return multiply

times_three = multiplier(3)
times_five = multiplier(5)

print(times_three(10))  # 결과: 30
print(times_five(10))   # 결과: 50

6. 주의사항: nonlocal 키워드

내부 함수에서 외부 함수의 변수를 단순히 읽는 것은 자유롭지만, 그 값을 수정하려면 nonlocal 키워드가 필요합니다. (전역 변수의 global과 유사한 역할입니다.)

7. 결론: 언제 내부 함수를 사용해야 할까?

내부 함수는 남용할 필요는 없지만, 코드가 복잡해지고 특정 로직이 한 함수 내에서만 의미가 있을 때 도입하면 코드의 응집력을 높여줍니다. 특히 데코레이터(Decorator)나 클로저를 공부하기 전 반드시 마스터해야 할 파이썬의 핵심 근간입니다.

8. 내용 출처

  • Python Documentation - "Scopes and Namespaces"
  • Real Python - "Python Inner Functions: What Are They Used For?"
  • Learning Python by Mark Lutz - O'Reilly Media
728x90