함수 내부에서 정의된 함수. 외부 함수의 변수에 접근 가능. 외부 함수가 실행을 마쳐서 접근이 불가능해진 상황에서 이 내부함수를 통해 접근 가능.
ex) closure
def outer_func(x):
def inner_func(y):
return x + y
return inner_func
closure_func = outer_func(10) # closure_func = innter_func with x = 10
print(closure_func(5)) # inner_func(5) with x = 10간단히 말하면, closure를 이용해서 (외부함수의 변수) + (내부함수) 세트만 유지가 가능하다. 이런걸 어디다 쓸까 싶은데, 다음과 같이 클래스로 구현하고 사용도 멤버함수를 불러야 하는 경우에 좀 더 간편히 사용가능하다.
ex) 특정 값을 항상 곱해주는 함수
class Mul:
def __init__(self, m):
self.m = m
def mul(self, n):
return self.m*n
def mul(m):
def wrapper(n):
return m*n
return wrapper
if __name__ == "__main__":
mul3 = Mul(3)
mul5 = Mul(5)
print(mul3.mul(10))
print(mul5.mul(10))
mul4 = mul(4)
print(mul4(10))특정 값을 항상 곱해주는 함수가 필요한데, 그 값을 동적으로 생성해야 한다면 위의 Mul 클래스와 같이 클래스 생성자를 이용해 구현이 가능하다. 그런데, closure를 사용하면, 위에서 mul()처럼 더 간편하게 구현과 사용이 된다.
위 예는 좀 추상적인, 실용적인가 싶은 예제였는데 실제로 어디에 사용이 가능할까? 대표적으로 로그를 출력하는 logger에 사용이 가능하다.
ex) 실 사용 예 : logger
from typing import Callable
import datetime
def logger_with_prefix(prefix: str) -> Callable[[str], None]:
def log_message(message):
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}][{prefix}]{message}")
return log_message
if __name__ == "__main__":
logger = logger_with_prefix("main")
logger("this is log message")[2026-05-29 15:31:45][main]this is log message로그의 prefix값을 미리 생성해놓고, 메세지만 출력하면 알아서 prefix를 더해 정해진 포맷으로 로그 출력이 가능하다.
자주 사용할까? 아직은 잘 모르겠다만, 최소한 파이썬 코드에서 closure로 구현된걸 읽어내는데 문제는 없을 것이다.