Python
클로저
haventmetyou
2023. 10. 17. 16:22
변수의 사용 범위 알아보기
x = 10 # 전역 변수
def foo():
print(x) # 전역 변수 출력
foo() # 함수 호출
10
print(x) # 전역 변수 출력
10
foo 함수에서 함수 바깥에 있는 변수 x의 값 출력, 함수 바깥에서도 x의 값 출력 가능
함수를 포함해 스크립트 전체에서 접근할 수 있는 변수를 전역 변수라 하고, 전역 변수에 접근할 수 있는 범위를 전역 범위라고 함
함수 안에서 전역 변수 변경
def foo():
x = 10 # 지역 변수
print(x) # 지역 변수 출력
foo() # 함수 호출
print(x) # 에러, foo의 지역 변수는 출력할 수 없음
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
x = 10
def foo():
x = 20
print(x)
foo()
20
print(x)
10
x = 10 # 전역 변수
def foo():
global x # 전역 변수 x를 사용하겠다 설정
x = 20 # x는 전역 변수
print(x) # 전역 변수 출력
foo()
20
print(x) # 전역 변수 출력
20
# x = 10 # 전역 변수
def foo():
global x
x = 20 # 지역 변수
print(x)
foo()
20
print(x)
20
네임스페이스
변수는 네임스페이스(namespace, 이름공간)에 저장됨
> locals 함수를 사용하면 현재 네임스페이스를 딕셔너리 형태로 출력
>>> # 전역 범위에서 네임스페이스 출력
>>> x = 10
>>> locals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'foo': <function foo at 0x0000019720A4CC20>, 'x': 10}
>>>
>>>
>>> # 함수 안에서 locals 사용
>>> def foo():
... x = 10
... print(locals())
...
>>> foo()
{'x': 10}
함수 안에서 함수 만들기
def print_hello():
hello = 'Hello, world!'
def print_messeage():
print(hello)
print_messeage()
print_hello()
Hello, world!
지역 변수 범위
def A():
x = 10 # A의 지역변수
def B():
x = 20
B()
print(x)
A()
10
def A():
x = 10 # A의 지역변수
def B():
x = 20
print(x)
B()
print(x) # 20 출력
A() # 10 출력
지역 변수 변경
nonlocal 지역변수
def A():
x = 10 # A의 지역변수
def B():
nonlocal x # 현재 함수의 바깥쪽에 있는 지역 변수 사용
# global x
x = 20 # A의 지역 변수 x에 20 할당
B()
print(x)
A()
20
# nonlocal이 변수 찾는 순서
def A():
x = 10 # A의 지역변수
y = 100
def B():
x = 20
def C():
nonlocal x
nonlocal y
x = x + 30
y = y + 300
print(x)
print(y)
C()
B()
A()
50
400
global로 전역 변수 사용
함수가 몇 단계든 상관없이 global 키워드를 사용하면 무조건 전역 변수 사용
x = 1
def A():
x = 10
def B():
x = 20
def C():
global x
x = x + 30
print(x)
C()
B()
A()
31
클로저 사용
def clac():
a = 3
b = 5
def mul_add(x):
return a * x + b
return mul_add
c = clac()
print(c(1), c(2), c(3), c(4), c(5))
8 11 14 17 20
함수를 둘러싼 환경(지역 변수, 코드 등)을 계속 유지하다가 함수를 호출할 때 다시 꺼내서 사용하는 함수를 클로저(closure)라고 함
위에서는 c에 저장된 함수가 클로저
클로저를 사용하면 프로그램의 흐름을 변수에 저장 > 지역 변수와 코드를 묶어서 사용하고 싶을 때 활용
클로저에 속한 지역 변수는 바깥에서 직접 접근할 수 없으므로 데이터를 숨기고 싶을 때 활용
람다로 클로저 만들기
def clac():
a = 3
b = 5
return lambda x: a * x + b
c = clac()
print(c(1), c(2), c(3), c(4), c(5))
클로저의 지역 변수 변경하기
def clac():
a = 3 # 함수 calc의 지역 변수
b = 5
total = 0
def mul_add(x):
nonlocal total
total = total + a * x + b
print(total)
return mul_add
c = clac()
c(1)
8
c(2)
19
c(3)
33