파이썬 - 클로저: 초보자를 위한 가이드
안녕하세요, 파이썬 프로그래머를 꿈꾸고 계신 분들! 오늘, 우리는 클로저의 세계로 흥미진진한 여정을 떠날 거예요. 이术语에 대해 들어본 적이 없다고 해도 걱정 마세요 – 이 튜토리얼을 끝내면 클로저가 무엇인지 이해하게 되는 것뿐만 아니라 자신의 코드에서 생성하고 사용할 수 있게 될 거예요. 그럼, 빠르게 담아보죠!
클로저란 무엇인가요?
마법의 상자라고 생각해보세요. 상자를 닫았을 때도 기억할 수 있는 것처럼. 그게 바로 프로그래밍에서 클로저란 거예요! 파이썬에서는 클로저가 메모리에 존재하지 않더라도 둘러싼 스코프에서 값을 기억하는 함수 객체입니다.
혼란스럽나요? 그럼 하나씩 정리해보죠:
- 다른 함수 안에 함수가 있습니다.
- 바깥 함수의 변수에 접근할 수 있습니다.
- 바깥 함수가 실행이 끝난 후에도 이 변수들을 기억합니다.
이를 통해 자신만의 데이터를 가지고 있는 기능을 만들어낼 수 있는 방법이라고 생각해보세요. 멋지죠?
중첩 함수
클로저에 더 깊이 들어가기 전에, 중첩 함수에 대해 이야기해봅시다. 이들은 단순히 다른 함수 안에 정의된 함수들입니다. 아래는 간단한 예제입니다:
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
result = outer_function(10)
print(result(5)) # 출력: 15
이 예제에서, inner_function
은 outer_function
내에 중첩되어 있습니다. 안쪽 함수는 바깥 함수의 x
매개변수에 접근할 수 있습니다. 이는 클로저를 이해하는 데 중요한 개념입니다.
변수 스코프
클로저를 진정으로 이해하려면, 파이썬에서 변수 스코프를 이해해야 합니다. 스코프는 세 가지 유형이 있습니다:
- 지역 스코프: 함수 내에 정의된 변수
- 둘러싼 스코프: 중첩 함수의 바깥 함수의 변수
- 전역 스코프: 모듈의 최상위 수준에 정의된 변수
아래는 이를 설명하는 예제입니다:
x = "저는 전역입니다!" # 전역 스코프
def outer():
y = "저는 바깥에서 왔습니다!" # 둘러싼 스코프
def inner():
z = "저는 지역입니다!" # 지역 스코프
print(x, y, z)
inner()
outer()
이 코드를 실행하면 세 가지 변수가 모두 인쇄됩니다. inner
함수는 세 가지 스코프의 변수에 모두 접근할 수 있습니다!
클로저 생성
이제 중첩 함수와 변수 스코프를 이해했으므로, 클로저를 생성해봅시다. 클로저는 중첩 함수가 둘러싼 스코프의 값을 참조할 때 발생합니다. 아래는 예제입니다:
def multiply_by(n):
def multiplier(x):
return x * n
return multiplier
times_two = multiply_by(2)
times_three = multiply_by(3)
print(times_two(5)) # 출력: 10
print(times_three(5)) # 출력: 15
이 예제에서, multiply_by
은 바깥 함수이고, multiplier
은 안쪽 함수입니다. 마법은 multiplier
를 반환할 때 일어납니다 - multiply_by
가 실행이 끝나도 n
의 값을 기억합니다. 이것이 클로저입니다!
한 단계씩 정리해보죠:
-
multiply_by
를 정의하여n
매개변수를 받습니다. -
multiply_by
내에multiplier
를 정의하여x
매개변수를 받습니다. -
multiplier
는 자신의 매개변수x
와 바깥 함수의n
을 사용합니다. -
multiplier
를multiply_by
에서 반환합니다. -
multiply_by(2)
를 호출하면 입력을 항상 2배로 곱는 함수를 반환합니다. - 마찬가지로,
multiply_by(3)
는 입력을 항상 3배로 곱는 함수를 반환합니다.
이게 클로저의 힘입니다 - 온-the-fly에 특화된 함수를 만들 수 있습니다!
nonlocal
키워드
때로는 안쪽 함수에서 둘러싼 스코프의 변수를 수정하고 싶을 수 있습니다. 파이썬은 이를 위해 nonlocal
키워드를 제공합니다. 아래는 예제입니다:
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
my_counter = counter()
print(my_counter()) # 출력: 1
print(my_counter()) # 출력: 2
print(my_counter()) # 출력: 3
이 예제에서, increment
은 count
변수를 기억하고 수정하는 클로저입니다. nonlocal
키워드는 count
가 지역 변수가 아니라 둘러싼 스코프의 변수라는 것을 파이썬에게 알려줍니다.
클로저의 실용적 사용
클로저는 단순한 트릭이 아니라 실용적인 응용이 있습니다! 몇 가지 예를 들어보죠:
- 데이터 숨기고 캡슐화
- 함수 팩토리 생성
- 데코레이터 구현
실제 세상의 예제를 살펴보죠. 온라인 스토어의 할인 시스템을 만들고 있다고 상상해봅시다:
def create_price_adjuster(discount):
def adjust_price(price):
return price * (1 - discount)
return adjust_price
black_friday_sale = create_price_adjuster(0.2) # 20% 할인
cyber_monday_sale = create_price_adjuster(0.15) # 15% 할인
original_price = 100
print(f"Black Friday price: ${black_friday_sale(original_price)}")
print(f"Cyber Monday price: ${cyber_monday_sale(original_price)}")
이 코드는 다른 판매 이벤트에 맞춘 다양한 가격 함수를 만들기 위해 같은 기본 함수를 사용합니다. 그것이 클로저의 힘입니다!
요약
축하합니다! 파이썬의 더 복잡한 기능 중 하나를 배웠습니다. 지금까지 다룬 내용을 요약해보겠습니다:
개념 | 설명 |
---|---|
클로저 | 둘러싼 스코프의 값을 기억하는 함수 |
중첩 함수 | 다른 함수 내에 정의된 함수 |
변수 스코프 | 변수의 가시성 (지역, 둘러싼, 전역) |
nonlocal |
둘러싼 스코프의 변수를 수정하는 키워드 |
기억해주세요, 강력한 도구는 클로저도 마찬가지로 과도하게 사용하면 코드가 이해하기 어려워질 수 있습니다. 실습하고 실험해보며, 곧 파이썬 프로처럼 클로저를 사용할 수 있을 거예요!
코딩을 즐기세요, 그리고 파이썬에서는 생활에서도 마찬가지로 내부(함수)에 무엇이 있는지가 중요합니다!
Credits: Image by storyset