[python] 클로저 사용하기
변수의 사용 범위 알아보기
# 변수의 사용 범위와 함수를 클로저 형태로 만드는 방법을 알아보자.
x = 10 # 전역 변수
def foo():
print(x) # 전역 변수 출력
foo()
print(x) # 전역 변수 출력
# 변수 x는 foo 함수에서도, 함수 바깥에서도 x의 값을 출력할 수 있다.
# 이처럼 함수를 포함하여 스크립트 전체에서 접근할 수 있는 변수를 전역 변수라고 한다.
# 그리고 전역 변수에 접근할 수 있는 범위를 전역 범위라고 한다.
# 이번에는 함수 안에서 따로 변수를 만들어보자
def foo2():
x = 20 # foo의 지역 변수
print(x) # foo의 지역 변수 출력
foo2() # foo의 지역 변수인 x가 출력, 20
print(x) # 전역 변수인 x가 출력, 10
# foo2 안의 x는 foo2 안에서 만들어졌기 때문에 foo2의 지역 변수이다.
# 따라서 지역 변수는 변수를 만든 지역 안에서만 접근할 수 있다.
# 지역 변수를 접근할 수 있는 범위를 지역 범위 라고 한다.
# 함수 안에서 전역변수에 접근하려면 global 키워드를 사용해야 한다.
def foo3():
global x # 전역 변수 x를 사용하겠다고 설정
x = 30 # 전역 변수 x의 값을 변경
print(x) # 전역 변수 x 출력
foo3()
print(x)
# 파이썬에서 변수는 namespace에 저장된다.
# locals 함수를 사용하면 현재 네임스페이스를 딕셔너리 형태로 출력할 수 있다.
print(locals())
def foo4():
x = 1
print(locals())
foo4()
함수 안에서 함수 만들기
# 함수 안에서 함수를 만들려면 def로 함수를 만들고 그 안에서 다시 def로 함수를 만들면 된다.
# def 함수이름1():
# 코드
# def 함수이름2():
# 코드
def print_hello():
hello = 'Hello, world!'
def print_message():
print(hello) # 바깥 함수의 지역 변수를 사용
print_message()
print_hello()
# 현재 지역의 바깥쪽에 있는 지역 변수에 접근하려면 nonlocal 키워드를 사용한다.
def func1():
x = 10
def func2():
nonlocal x
x = 20
func2()
print(x)
func1()
# nonlocal은 현재 지역 기준 가장 가까운 지역의 변수를 찾는다
def foo1():
x = 10
y = 100
def foo2():
x = 20
def foo3():
nonlocal x # foo2의 지역변수 x를 사용
nonlocal y # foo2에 y가 없으므로 한단계 더 밖으로 나가서 foo1의 y를 사용
x = x + 30
y = y + 300
print(x, y)
foo3()
foo2()
foo1()
# global은 어느 지역이든 상관없이 무조건 전역 변수를 사용
클로저 사용하기
# 함수를 클로저 형태로 만드는 방법을 알아보자.
# 다음은 mul_add 자체를 반환하는 함수이다.
def calc():
a = 3
b = 5
def mul_add(x):
return a * x + b # 함수 바깥의 지역변수 a, b를 사용해 계산
return mul_add # mul_add 함수를 반환
# 함수를 둘러싼 환경을 유지하다가 함수를 호출할 때 다시 꺼내서 사용하는 함수를 클로저
# 클로저에 속한 지역 변수는 바깥에서 직접 접근할 수 없으므로 데이터 숨기고 싶을 때 활용
# 여기서는 c에 저장된 함수가 클로저
c = calc()
print(c(1), c(2)) # 8 11
# 클로저는 다음과 같이 lambda로도 만들 수 있다.
def calc2():
a = 3
b = 5
return lambda x: a * x + b # 람다 표현식을 반환
c = calc2()
print(c(1), c(2), c(3))
# 클로저의 지역 변수를 변경하고 싶다면 nonlocal을 사용
def calc3():
a = 3
b = 5
total = 0
def mul_add(x):
nonlocal total
total = total + a * x + b # 덧셈의 결과를 total에 누적
print(total)
return mul_add
c = calc3()
c(1) # 8
c(2) # 19
Leave a comment