파이썬의 클로저(Clsure) 사용법

파이썬의 클로저(Clsure) 사용법

Python
파이썬의 클로저(Clsure) 사용법
Author

gabriel yang

Published

October 2, 2024

파이썬의 클로저(Clsure) 사용법

파이썬의 클로저(Closure)는 함수가 정의된 환경을 기억하고, 그 환경에 속한 변수들을 함수가 호출될 때까지 유지하는 기능입니다. 간단히 말해, 내부 함수가 외부 함수의 변수를 참조하면서도 그 값을 유지할 수 있는 메커니즘입니다.

이번 글에서는 클로저의 개념과 사용하는 이유, 그리고 예제 코드를 통해 이를 어떻게 활용할 수 있는지 설명하겠습니다.

1. 클로저(Closure)란?

클로저는 함수 내부에 또 다른 함수를 정의하고, 그 내부 함수가 외부 함수의 변수를 참조할 때 발생합니다. 내부 함수는 외부 함수의 스코프(scope)에 있는 변수들을 기억하고, 외부 함수의 실행이 끝난 후에도 해당 변수를 사용할 수 있습니다.

클로저의 조건

클로저가 되기 위한 조건은 다음과 같습니다:

  1. 함수 내부에 또 다른 함수가 정의되어야 함.
  2. 내부 함수가 외부 함수의 변수를 참조해야 함.
  3. 외부 함수가 종료된 후에도 참조한 변수를 사용할 수 있어야 함.

기본 구조

def outer_function():
    x = 10  # 외부 함수의 변수

    def inner_function():
        print(x)  # 내부 함수가 외부 함수의 변수를 참조
    return inner_function

위 예시에서 inner_functionouter_function의 변수 x를 참조합니다. outer_function이 종료된 후에도 inner_functionx를 기억하고 사용할 수 있습니다.

2. 클로저를 사용하는 이유

클로저는 데이터를 캡슐화하고 상태를 기억하는데 유용합니다. 외부 함수의 변수를 기억하는 기능 덕분에, 클로저는 마치 객체의 속성처럼 데이터를 저장하고, 상태를 유지할 수 있습니다.

클로저를 사용하는 이유는 다음과 같습니다:

  1. 상태 유지: 함수가 호출된 이후에도 외부 함수의 상태(변수)를 유지할 수 있습니다.
  2. 데이터 은닉: 클로저를 통해 외부에서 직접 접근할 수 없는 변수를 사용할 수 있습니다.
  3. 함수형 프로그래밍: 클로저는 고차 함수나 콜백 함수에서 자주 사용됩니다. 이러한 함수형 프로그래밍 패턴에서 클로저는 중요한 역할을 합니다.

3. 클로저 사용 예시

예시 1: 기본 클로저 예시

def outer_function():
    x = 10  # 외부 함수 변수

    def inner_function():
        print(f"외부 함수의 변수 x: {x}")  # 외부 변수 참조
    return inner_function  # 내부 함수 반환

# 외부 함수를 호출하고 내부 함수를 반환받음
closure = outer_function()

# 클로저 함수 실행
closure()  # 외부 함수가 종료되었음에도 x 값을 출력

출력:

외부 함수의 변수 x: 10

이 예시에서 outer_function이 종료된 후에도 inner_functionx 변수를 기억하고 있습니다. closure()를 호출하면, 외부 함수의 변수 x를 사용할 수 있습니다.

예시 2: 상태를 기억하는 클로저

클로저는 호출될 때마다 상태를 기억하고 그 상태를 바탕으로 동작할 수 있습니다. 이를 통해, 외부 함수의 변수를 마치 객체의 속성처럼 사용할 수 있습니다.

def make_multiplier(n):
    def multiplier(x):
        return x * n  # 외부 함수 변수 n을 참조
    return multiplier

# 2배수와 3배수를 계산하는 클로저 생성
times_two = make_multiplier(2)
times_three = make_multiplier(3)

# 클로저 실행
print(times_two(10))  # 20
print(times_three(10))  # 30

출력:

20
30

이 예시에서 make_multiplier는 내부 함수 multiplier를 반환하며, n 값을 기억합니다. times_twon이 2인 상태를 유지하고, times_threen이 3인 상태를 유지합니다. 이를 통해 다양한 배수를 계산하는 함수들을 생성할 수 있습니다.

예시 3: 클로저를 사용한 데이터 은닉

클로저는 데이터 은닉에도 사용될 수 있습니다. 외부 함수의 변수를 클로저로 감싸서, 해당 변수에 대한 직접적인 접근을 막을 수 있습니다.

def bank_account(initial_balance):
    balance = initial_balance  # 외부 함수의 변수

    def deposit(amount):
        nonlocal balance
        balance += amount
        return balance

    def withdraw(amount):
        nonlocal balance
        if balance >= amount:
            balance -= amount
            return balance
        else:
            return "잔액 부족"

    return deposit, withdraw

# 클로저로 은행 계좌 생성
deposit_fn, withdraw_fn = bank_account(100)

print(deposit_fn(50))  # 입금 후 잔액: 150
print(withdraw_fn(30))  # 출금 후 잔액: 120
print(withdraw_fn(200))  # 잔액 부족

출력:

150
120
잔액 부족

이 예시에서 balance 변수는 외부에서 직접 접근할 수 없습니다. 오직 클로저로 반환된 depositwithdraw 함수만이 balance에 접근하고 수정할 수 있습니다. 이렇게 하면 중요한 데이터를 은닉하고, 특정 함수로만 접근하도록 제한할 수 있습니다.

4. 클로저와 nonlocal 키워드

클로저 내부에서 외부 함수의 변수를 수정하려면 nonlocal 키워드를 사용해야 합니다. nonlocal은 외부 함수에 선언된 변수를 내부 함수에서 참조하고 수정할 수 있도록 해줍니다.

예시: nonlocal 사용

def outer_function():
    x = 10  # 외부 함수 변수

    def inner_function():
        nonlocal x  # 외부 함수의 변수를 수정
        x += 1
        return x
    return inner_function

closure = outer_function()
print(closure())  # 11
print(closure())  # 12

출력:

11
12

여기서 nonlocal 키워드를 사용하여 x 값을 수정할 수 있습니다. closure()를 호출할 때마다 x가 1씩 증가합니다.

5. 클로저와 객체 지향 프로그래밍 비교

클로저는 상태를 유지하고 데이터를 은닉하는 면에서 객체 지향 프로그래밍(OOP)의 객체와 유사합니다. 하지만, 클로저는 함수를 통해 상태를 유지하는 반면, 객체는 클래스와 메서드를 사용합니다. 클로저는 가볍고 간단한 상태 관리를 위해 사용되며, OOP에서 클래스를 사용하는 것보다 더 간결한 표현을 제공합니다.

클로저 vs 객체 지향 예시

클로저와 클래스의 차이를 간단한 카운터 예시로 비교해 보겠습니다.

클로저를 사용한 카운터

def counter():
    count = 0

    def increment():
        nonlocal count
        count += 1
        return count

    return increment

count_fn = counter()
print(count_fn())  # 1
print(count_fn())  # 2

출력

1
2

클래스를 사용한 카운터

class Counter:
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1
        return self.count

counter_obj = Counter()
print(counter_obj.increment())  # 1
print(counter_obj.increment())  # 2

출력

1
2

이 두 코드는 같은 기능을 하지만, 클로저는 더 간단하고 함수적인 방식으로 상태를 유지합니다. 반면, 클래스는 더 명시적인 객체 구조를 사용합니다.

결론

파이썬의 클로저는 함수가 정의된 환경을 기억하고, 그 환경 내의 변수들을 계속 사용할 수 있는 강력한 도구입니다. 클로저를 사용하면 데이터를 은닉하고, 상태를 기억하며, 반복적인 동작을 간결하게 구현할 수 있습니다. 객체 지향 프로그래밍과 비슷한 기능을 제공하지만, 더 가볍고 함수적인 패턴을 선호하는 경우 클로저를 활용하는 것이 좋습니다.

클로저는 함수형 프로그래밍에서 자주 사용되며, 상황에 맞게 클로저를 활용하면 코드의 유연성과 재사용성을 높일 수 있습니다!

Date Title Author
Jan 1, 3000 전체 카테고리 gabriel yang
Nov 26, 2024 VSCode에서 Python 디버깅 (launch.json 설정) gabriel yang
Nov 23, 2024 Python 설치된 패키지 확인, 설치와 복원하기 gabriel yang
Oct 14, 2024 JSON 파일에서 특정 key의 값 변경 후 저장하는 방법 gabriel yang
Oct 10, 2024 날짜 문자열을 날짜 형식으로 변환하기 gabriel yang
Oct 8, 2024 Request를 통한 JIRA REST API 사용방법 gabriel yang
Oct 8, 2024 Request 라이브러리 사용방법 gabriel yang
Oct 8, 2024 Requests 라이브러리로 베이직 인증 API 호출하기 gabriel yang
Oct 7, 2024 Python으로 SSH를 제어하기 gabriel yang
Oct 7, 2024 Pytest로 테스트하기 gabriel yang
Oct 7, 2024 Pytest 기본적인 테스트 실행 방법 gabriel yang
Oct 7, 2024 Pytest Fixture 개념과 필요성 gabriel yang
Oct 7, 2024 CI 환경에서 Pytest 사용하기 gabriel yang
Oct 7, 2024 파이썬에서 테스트 코드 리팩토링 기법 gabriel yang
Oct 5, 2024 Python os 모듈을 이용한 파일과 폴더 관리 gabriel yang
Oct 5, 2024 Python shutil 모듈을 이용한 파일과 폴더 관리 gabriel yang
Oct 5, 2024 MongoDB 데이터베이스 백업 및 복원 방법 gabriel yang
Oct 5, 2024 Python jira 라이브러리를 이용해 JIRA를 관리하는 방법 gabriel yang
Oct 4, 2024 Python에서 JSON 파일 읽기 및 데이터 활용 gabriel yang
Oct 4, 2024 JSON 데이터 수정하기 gabriel yang
Oct 4, 2024 JSON 파일의 구성요소와 구조 gabriel yang
Oct 4, 2024 Python에서 Git명령 사용하기 gabriel yang
Oct 3, 2024 파이썬으로 클래스 정의하는 방법 gabriel yang
Oct 3, 2024 파이썬의 상속(Inheritance) 이해하기 gabriel yang
Oct 3, 2024 파이썬 클래스의 self 이해하기 gabriel yang
Oct 3, 2024 파이썬에서 추상 클래스(Abstract Class) 사용하기 gabriel yang
Oct 3, 2024 파이썬 클래스 활용 예시 gabriel yang
Oct 3, 2024 파이썬 클래스와 모듈 gabriel yang
Oct 3, 2024 파이썬에서 Lock을 사용하는 이유와 방법 gabriel yang
Oct 2, 2024 Python에서 zip()을 사용하는 이유와 방법 gabriel yang
Oct 2, 2024 파이썬 시퀀스 슬라이싱 gabriel yang
Oct 2, 2024 파이썬에서 Generator를 사용하는 이유와 사용법 gabriel yang
Oct 2, 2024 파이썬의 @property 기능 gabriel yang
Oct 2, 2024 파이썬 시퀀스 언패킹 gabriel yang
Oct 2, 2024 파이썬 데이터 정렬 gabriel yang
Oct 2, 2024 파이썬 딕셔너리 key 예외처리하기 gabriel yang
Oct 2, 2024 파이썬의 defaultdict 사용법 gabriel yang
Oct 2, 2024 파이썬의 try-except 사용법 gabriel yang
Oct 2, 2024 파이썬의 가변인자 사용법 gabriel yang
Oct 2, 2024 파이썬의 컴프리헨션(Comprehension) 사용법 gabriel yang
Oct 1, 2024 파이썬 가상환경 설정 gabriel yang
Oct 1, 2024 파이썬을 이용한 테스트 자동화 gabriel yang
Oct 1, 2024 파이썬 docstring을 사용하는 이유와 방법 gabriel yang
Oct 1, 2024 파이썬 yield 제너레이터와 효율적인 반복 처리 gabriel yang
Oct 1, 2024 파이썬 데이터 언패킹 gabriel yang
Oct 1, 2024 Python에서 enumerate를 사용하는 이유와 사용 방법 gabriel yang
Sep 30, 2024 Python 설치 및 기본 파이썬 버전 설정 gabriel yang
Sep 30, 2024 Python을 이용한 폴더 전체 복사 방법 gabriel yang
Sep 30, 2024 Public Key와 Private Key의 역할 gabriel yang
Sep 23, 2024 Python의 @dataclass 데코레이터 gabriel yang
Aug 30, 2024 Python shell명령 수행하기 (Subprocess) gabriel yang
Aug 29, 2024 Google Colab에서 라이브러리 설치하기 gabriel yang
Aug 1, 2024 환경변수 설정하고 Python에서 읽어오기 gabriel yang
Jan 1, 2024 코루틴(coroutine)과 이벤트 루프 gabriel yang
No matching items
Back to BLOG LIST