데커레이터라는 표현은 구문 트리를 파싱하고 애너테이션하는 컴파일러 분야에서의 용법과 관련이 크다
함수 데커레이터 : 소스 코드에 있는 함수를 ‘표시’해서 함수의 작동을 개선
데커레이터(decorator)는 다른 함수를 인수로 받는 callable
데커레이터는 데커레이트된 함수에 어떤 처리를 수행, 함수를 반환하거나 함수를 다른 함수나 callable 객체로 대체
@decorate
def target():
print("running target()")
def target():
print("running target()")
target = decorate(target)
엄밀히 말하면 데커레이터는 편리 구문이다 (syntactic sugar)
→ 그렇지만 런타임에 프로그램 행위를 변경하는 메타프로그래밍을 할 때 데커레이터가 상당히 편함
그래서 데커레이터는...
데커레이터의 핵심 특징 → 데커레이트된 함수가 정의된 직후에 실행
정의된 직후 → 일반적으로 파이썬이 모듈을 로딩하는 시점, 즉 임포트 타임
case 1
b = 6
def test_f(a):
print(a)
print(b)
test_f(3)
>> 3
>> 6
case 2
b = 6
def test_f(a):
print(a)
print(b)
b = 9
test_f(3)
Traceback (most recent call last):
File "/Users/sanghunmoon/Library/Application Support/JetBrains/PyCharm2021.1/scratches/scratch_4.py", line 8, in <module>
test_f(3)
File "/Users/sanghunmoon/Library/Application Support/JetBrains/PyCharm2021.1/scratches/scratch_4.py", line 5, in test_f
print(b)
**UnboundLocalError: local variable 'b' referenced before assignment**
Process finished with exit code 1
파이썬이 함수 본체를 컴파일할 때 b가 함수 안에서 할당되므로 b를 지역 변수로 판단
생성된 바이트코드를 보면 case 2 에서는 지역 환경에서 변수 b를 가져오려 한다
나중에 test_f(3) 을 호출할 때, test_f 의 본체는 지역변수 b의 값을 가져오려 할 때 b가 바인딩되어 있지 않다는 것을 발견
# case 1
4 0 LOAD_GLOBAL 0 (print)
2 LOAD_FAST 0 (a)
4 CALL_FUNCTION 1
6 POP_TOP
5 8 LOAD_GLOBAL 0 (print)
**10 LOAD_GLOBAL 1 (b)**
12 CALL_FUNCTION 1
14 POP_TOP
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
# case 2
4 0 LOAD_GLOBAL 0 (print)
2 LOAD_FAST 0 (a)
4 CALL_FUNCTION 1
6 POP_TOP
5 8 LOAD_GLOBAL 0 (print)
**10 LOAD_FAST 1 (b)**
12 CALL_FUNCTION 1
14 POP_TOP
6 16 LOAD_CONST 1 (9)
18 STORE_FAST 1 (b)
20 LOAD_CONST 0 (None)
22 RETURN_VALUE
함수 본체에서 정의하지 않고 참조하는 비전역(nonglobal) 변수를 포함하는 확장 범위를 가진 함수
지역 범위에 바인딩 되어 있지 않은 변수
어떤 코드블록 안에서 사용되지만, 글로벌 변수도 아니고 그 블록 내에 정의하지도 않은 변수
def make_averager():
################### CLOSURE START
series = [] # 자유 변수 (free variable)
def averager(new_value):
series.append(new_value)
total = sum(series)
return total / len(series)
################### CLOSURE END
return averager
→ 클로저는 함수를 정의할 때 존재하던 자유 변수에 대한 바인딩을 유지하는 함수
함수를 정의하는 범위가 사라진 후에 함수를 호출해도 자유 변수에 접근할 수 있음
함수가 비전역 외부 변수를 다루는 경우는 그 함수가 다른 함수 안에 정의된 경우 뿐
전문가를 위한 파이썬
제타위키
해당 글은 전문가를 위한 파이썬을 정리한 글입니다
저작권에 문제가 있으면 삭제하도록 하겠습니다