728x90
반응형
33. 클로저 사용
33.1 변수의 사용 범위 알아보기
x = 10 # 전역변수(global variable)
# ----------- 전역범위 시작 -------------
def foo():
print(x)
foo()
print(x)
# ----------- 전역범위 끝 ---------------
==========================
10
10
# ----------- 지역범위 시작 -------------
def foo():
x = 20 # 지역변(local variable)
print(x)
# ----------- 지역범위 끝 -------------
foo()
==========================
20
# 함수 안에서 전역 변수 변경
x = 10 # 전역변수
def foo():
x = 20 # 지역변수
print(x) # 지역변수 출력
foo()
print(x) # 전역변수 출력
==========================
20 # 지역변수만 변경됨
10 # 전역변수는 변경되지 않음
# 전역변수 사용
def foo():
global x
x = 20
print(x)
foo()
print(x)
==========================
20
20
# 전역변수가 없는 경우 선언하여 사용
def foo():
global y
y = 20
print(y)
foo()
print(y)
==========================
20
20
# 네임스페이스
z = 10
print(locals())
==========================
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10ab58f10>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Users/cheryl/Documents/workspace/practice2022/python-coding/33.py', '__cached__': None, 'lineBoard': '\n==========================\n', 'x': 20, 'foo': <function foo at 0x10aaf4d30>, 'y': 20, 'z': 10}
def foo():
a = 10
print(locals())
foo()
==========================
{'a': 10}
33.2 함수안에 함수
- 범위 알기
def print_hello():
hello = 'hello, world'
def print_message():
print(hello)
print_message()
print_hello()
==========================
hello, world
- 지역변수 변경
# 지역변수 범위 변경하기
def A():
x = 10
def B():
x = 20
B()
print(x) # A의 지역변수 출력 X
A()
==========================
10
# 함수에서 변수를 만들면 항상 현재 함수의 지역 변수가 된다
# 따라서 B()의 x는 B함수의 지역변수를 선언한 것일뿐
# A()의 지역변수이자 함수 내의 전역변수는 변경되지 않는다.
# nonlocal 지역변수
def A():
x = 10
def B():
nonlocal x # 현재 함수의 바깥쪽에 있는 지역 변수 사용
x = 20 # A의 지역 변수 x에 20 할당
B()
print(x) # A의 지역 변수 x 출력
A()
==========================
20
- nonlocal의 변수 찾는 순서: 현재 함수에서 가장 가까운 함수부터 찾는다
def A():
x = 10
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로 전역변수 사용
x = 1
def A():
x = 10
def B():
x = 20
def C():
global x
x = x + 30
print(x)
C()
B()
A()
==========================
31
33.3 클로저 함수
def calc():
a = 3
b = 5
def mul_add(x):
return a * x + b # 함수 바깥쪽에 있는 지역 변수 a, b를 사용하여 계산
return mul_add # mull_add를 만든 후, 이 함수를 바로 호출하지 않고 함수자체를 반환
# 반환할때는 ()없이 함수명만 반환해야 함 !!
c = calc()
print(c(1), c(2), c(3), c(4), c(5))
==========================
8 11 14 17 20
클로저 함수
함수를 둘러싼 환경(지역 변수, 코드 등)을 계속 유지하다가,
함수를 호출할 때 다시 꺼내서 사용하는 함수
* 클로저를 사용하면 프로그램의 흐름을 변수에 저장할 수 있다.
* 클로저에 속한 지역 변수는 바깥에서 직접 접근할 수 없으므로 데이터를 숨기고 싶을 때 활용
- 람다로 클로저 만들기
def calc():
a = 3
b = 5
return lambda x: a * x + b
c = calc()
print(c(1), c(2), c(3), c(4), c(5))
==========================
8 11 14 17 20
33.5 연습문제 : 호출 횟수를 세는 함수 만들기
def counter():
i = 0
def count():
nonlocal i
i += 1
return i
return count
c = counter()
for i in range(10):
print(c(), end=' ')
==========================
1 2 3 4 5 6 7 8 9 10
- 해설
# 클로저를 이용하면 함수 내 지역변수 값이 변경된 값으로 유지된다
33.6 심사문제 : 카운트다운 함수 만들기
def countdown(n):
i = n + 1
def count():
nonlocal i
i -= 1
return i
return count
n = int(input())
c = countdown(n)
for i in range(n):
print(c(), end=' ')
==========================
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
QnA. 자주 묻는 질문
일급객체
- 변수나 데이터 구조에 넣을 수 있어야 한다.
- 매개변수에 전달할 수 있어야 한다.
- 반환값으로 사용할 수 있어야 한다.
일급 함수는 일급 객체의 조건을 만족하면서, 실행 중에 함수를 생성할 수 있어야 한다.
파이선에서는 def안에서 def로 함수를 만들거나, lambda를 사용하여 실행 중에 함수를 생성할 수
있으므로 파이선의 함수는 일급 함수이다.
*** 파이선은 switch 문법이 없지만, 딕셔너리와 람다 표현식을 사용하면 switch처럼 사용할 수 있다.
switch = {
'+': lambda x, y: x + y, # 람다 표현식으로 실행할 코드를 작성
'*': lambda x, y: x * y
}
x = '+'
try:
print(switch[x](10, 20)) # 딕셔너리에 키를 지정하는 방식
except KeyError:
print('default') # 딕셔너리에 키가 없을 때는 기본 값
==========================
30
728x90
반응형
'Language > Python' 카테고리의 다른 글
[코딩도장]35.클래스 속성과 정적, 클래스 메서드 (0) | 2022.03.29 |
---|---|
[코딩도장]34.클래스 (0) | 2022.03.28 |
[코딩도장]32.람다표현식 (0) | 2022.03.26 |
[코딩도장]31.재귀호출 (0) | 2022.03.26 |
[코딩도장]30. 위치 인수와 키워드 인수 사용 (0) | 2022.03.25 |