2003 words
10 minutes
[Python] Closure, Decorator
개요
파이썬 함수형 프로그래밍을 이해하기 위해 파이썬 함수의 scope 과 데코레이터에 대해 알아본다. 여기서 주로 다루는 컨셉은 아래와 같다.
- Closure
- Scope
- lexical scope
- global scope
- free variable
- decorator
Closure
클로저는 간단히 말해 함수 안에 내부 함수(inner function)를 구현하고 그 내부 함수를 반환하는 함수를 말한다. 이때 외부 함수는 자신이 가진 변숫값 등을 내부 함수에 전달하여 실행되도록 한다.
Closure 핵심요소
클로저의 핵심은 Lexical Scope(렉시컬 스코프)와 Free Variable(자유 변수), 그리고 함수 객체(Function Object)이다.
Lexical Scope은 inner function이 정의된 환경 그 자체이며 Free Variable은 inner function에서 사용되는 외부 함수의 지역 변수를 말한다.
클로저는 자신이 생성된 환경을 기억하고 있으며, 외부 함수의 실행이 끝난 후에도 환경을 유지하는 함수 객체이다.
Concept
- Scope : 프로그램 내에서 객체가 유효함을 표시하기 위한 범위이다. Scope은 기본적으로 제어할 수 있냐 없냐의 문제이다.
- Lexical Scope : 함수를 선언한 지점의 변수와 함수를 포함한 환경을 의미하며 정적 스코프(Static Scope) 이라고도 한다. Nested Function에서 inner function이 더 상위 범위에 있는 변수와 함수에 접근할 수 있음을 의미한다. 기본적으로 함수의 호출(call)지점이 아니라 선언(declare) 지점에 따라 inner function이 영향을 주는 범위가 달라지는 것을 의미한다.
- Closure : 환경을 캡처하는 함수 오브젝트. 클로저는 Lambda와 같은 함수 오브젝트의 일종으로 자신이 정의된 환경(Lexical Scope)을 캡처해서 추후 그 환경에 접근할 수 있게끔 한다. 환경을 캡처한다는 것은 자신을 둘러싼 Scope의 상태값을 보존한다는 것이다. 이는 내부 상태를 유지하면서 외부로부터 데이터를 은닉할 수 있게 해준다.
- Free Variable : 클로저 내부 함수에서 사용되는 외부 함수의 지역 변수를 말한다. 클로저는 자신이 생성될 때의 환경(Lexical)에 있는 모든 변수를 기억하고 있다. 이러한 변수를 자유 변수라고 한다.
lambda와의 차이점
환경 캡처방식
# Lambda : 현재 스코프의 변수만 참조 가능multiplier = 2lambda_multiply = lambda x: x * multiplier
# Closure : 자체적인 환경 생성 및 유지def create_multiplier(factor): def multiply(x): return x * factor return multiplyclosure와 lambda 조합하기
def create_processor(initial): count = initial # 클로저 내에서 람다 사용 processors = { 'add': lambda x: x + count, 'multiply': lambda x: x * count, 'power': lambda x: x ** count }
def process(operation, value): nonlocal count count += 1 return processors[operation](value)
return process
proc = create_processor(2)print(proc('add', 3)) # 5print(proc('multiply', 3)) # 9Decorator
Decorator 핵심
데코레이터의 핵심은 기존 함수를 수정하지 않고 기능을 추가하거나 변경하는 것으로 트랜잭션 처리나 로깅과 같은 횡단 관심사의 모듈화를 통해 재사용성을 높이는 것이다.
이를 통해 핵심 로직과 부가 기능을 분리하여 코드의 가독성과 유지보수성을 높일 수 있다.
Concept
- Decorator : 데코레이터 패턴. 기본적인 컨셉은 기존의 함수를 수정하지 않고 기능을 추가하거나 변경하는 것이다. 일종의 함수형 패턴으로 원본 함수를 감싸는 Wrapper를 통해 전처리, 후처리, 예외처리 등의 횡단 관심사를 모듈화 하고 재사용하는데 사용한다.
Python 데코레이터 기본 패턴
def decorator(func): # 데코레이터 함수 def wrapper(*args, **kwargs): # Wrapper pre_func() # 함수 실행 전 실행 result = func(*args, **kwargs) # 원본 함수 실행 post_func() # 함수 실행 후 실행 return result return wrapper # 래퍼 함수 반환
@decorator # 데코레이터 구문def target_function(): # 대상 함수 passCase 1
def f1(func): def wrapper(*args, **kwargs): print("Started") val = func(*args, **kwargs) print("Ended") return wrapper
@f1 # f를 불러올 때마다 자동적으로 f1 인자로 f 가 전달된다. function alias 가 자동으로 생성된다.def f(a, b=9): pprint(a, b)
f("Hi")
@f1def add(x, y): return x + y
pprint(add(4, 5))횡단관심사의 모듈화
ex) 횡단관심사의 모듈화
# 공통기능의 모듈화@transaction # 트랜잭션 처리def save_user(): pass
@transactiondef update_order(): pass
@transactiondef delete_item(): passReference
- Python Functional Programming
[Python] Closure, Decorator
https://yjinheon.netlify.app/posts/01programming/python/functional/python-02_closure_deco/