장고를 이용한 웹 페이지 제작 중 데커레이터 사용에서 고통 받으며 공부하게 되었다..
데커레이터는 다른 함수를 인수로 받는 콜러블(데커레이터된 함수)이다.
# 예시를 위해 만든 데커레이터
def decorator(func):
print('running decorator')
return func
@decorator
def func()
print('running func')
# func = decorator(func) 데커레이터가 적용된 함수를
# 우리가 이해하기 좋은 형태로 만들었다.
func()
------------------------------------------
> running decorator
> running func
위의 예제와 같이 데커레이터를 사용한 함수를 감싸주는(wrapping) 해주는 형태로 동작을 하게 된다.
파이썬에서는 동작 시점을 크게 두 가지로 나누는 것 같다.
사실 내가 파이썬을 조금 공부하면서 느낀 것은 두 가지 동작에 겹치는 부분이 있는 것 같기는 하다.
데커레이터 같은 경우는 임포트 타임 시점에서 실행됨을 알 수 있다.
확인을 위해 몇 가지 코드를 실행시켜보았다.
# decorators.py
print('test start')
def decorators(func):
print('decorator called')
return func
@decorators
def inner_function():
print('inner function called')
if __name__ == '__main__':
print('main start')
inner_function()
print('main end')
print('test end')
-------------------------------
# import time
> test start
> decorator called
> test end
# run time
> test start
> decorator called
> main start
> inner function called
> main end
> test end
위의 결과를 보면 알겠지만 데커레이터 같은 경우는 임포트 타임에서 실행된다.
파이썬 프레임워크인 장고에서 특정 기능을 이용할 때 만약 특정 권한이 필요하다면 그것을 확인하는 기능(ex, 로그인 여부) 등에서 사용하고는 한다.
# 사용자가 로그인을 하지 않으면 해당 함수를 실행시킬 수 없다
@login_required
def write_view(request):
...
데커레이터를 제대로 사용하려면 클로저에 대해서 알아야 한다고 한다.
클로저에 관해서 이해한 바를 한문장으로 표현한다면 아래와 같지 않을까 싶다
함수가 비전역 외부 변수를 다루는 것
말 그대로 global()을 이용한 전역 변수가 아닌 외부 변수를 이용하는 경우를 뜻한다.
다양한 책 또는 코드등을 살펴봐도 이런 경우는 함수가 다른 함수 안에 정의된 경우 밖에 없었다.
파이썬에서 클로저란 '내부함수에서 외부 함수의 변수를 다루게 되는 경우'인 것 같다.
내부 함수에서 외부 함수에 있는 변수에 값을 증가(+=)시키려고 하면 변수 범위에 관련된 에러가 뜬다.(이 부분까지 추가하기엔 너무 길다.)
UnboundLocalError: local variable '[variable]' referenced before assignment
말 그대로 아직 선언되지 않은 지역 변수를 사용했다는 뜻이다. 이때는 변수 앞에 'nonlocal' 키워드를 이용해 내부 함수 내에서 선언해주면 된다.
def outter():
a = 1
def inner():
nonlocal a
a += 1
전문가를 위한 파이썬 - 루시아누 하말류