5-2 변수 스코프 & 람다 함수
- 변수 스코프(Scope) : 변수를 접근할 수 있는 범위
1. 전역 (Global) & 지역 변수 (Local)
- 전역 변수 : 함수 외부에 정의된 변수, 코드 전역에서 접근 가능
- 지역 변수 : 함수 내부에 정의된 변수, 함수가 실행중일 때만 유효함.
a = 10
def func() :
b = 20
print(a , b)
func()
c = 30
def outer() :
a = 10
def inner() :
b = 20
print(f'{a=} {b=} {c=}')
inner()
outer()
2. 파이썬 변수 검색 규칙 : LEGB 스코프
- L (local : 지역) > E (enclosing : 외부 함수) > G (global : 전역) > B(builtin : 내장)
a = 'Global'
def outer() :
a = 'Enclosing'
print('outer: ' a)
def inner() :
a = 'Local'
print('inner: 'a)
3. global 키워드
a = 'Global'
def outer() :
a = 'Enclosing'
print('outer: ', a)
def inner() :
global a
a = '000'
print('inner: ',a)
inner()
outer()
4. 일급 함수 (First-Class Function)
- 함수와 변수를 동일하게 취급
- 함수의 매개변수로 함수를 사용할 수 있다 : 콜백 함수
- 함수의 반환값으로 함수를 사용할 수 있다 : 팩토리 함수, 클로저
def callback2() :
print('callback()')
def func(callback) :
print('func()')
callback()
func(callback2)
def outer(num1):
def inner(num2):
return 10 + num2
return inner
a = outer(10)
print(a(20))
print(a(100))
- return한 inner 함수에서 계속 num1을 사용하기 때문에
num1을 함수 종료시에 자원이 해제되는 콜 스택이 아닌
힙 영역에 저장하면서 num1은 10으로 고정된다(클로저)
5. lambda 함수
- 함수를 일회용으로 사용하는 경우 한줄의 식으로 간단하게 함수 정의
- 일회용으로 사용되기 때문에 매개변수 이름도 최대한 간결하게 한글자로 선언
lambda 매개변수1, 매개변수2 : 처리 부분
square = lambda num: num ** 2
square(10)
def change_numbers(callback, *args):
numbers = list(args)
for i in range(len(numbers)):
numbers[i] = callback(numbers[i])
return numbers
change_numbers(lambda x: x ** 2, 10, 20, 30)
6. 전역 변수와 지역 변수의 이름 충돌과 은닉 법칙
7. lmabda, map(), filter()을 활용한 데이터 일괄 제공
- map() : 변환 작업
- filter() : 특정 조건에서 데이터 선별
fruits = ['사과', '오렌지', '망고']
result = list(map(lambda x: f'**{x}**', fruits))
print(result)
numbers = [*range(1, 11)]
print(list(filter(lambda x : x % 2 == 1, numbers)))
5-3 클로저 & 데코레이터
1. 파이썬 함수의 일급 객체 특성과 고차함수
2. 클로저(Closure)
def outer():
num1 = 10
def inner():
num2 = 20
print(num1 + num2)
return inner
inner = outer()
inner()
- 고차 함수 (Higher Order Function)
def add(num1):
def _add(num2):
def __add(num3):
return num1 + num2 + num3
return __add
return _add
a = add(10)
b = a(20)
c = b(30)
print(c)
print(add(10)(20)(30))
add10 = add(10)
print(add10(30)(40))
add10_20 = add(10)(20)
print(add10_20(30))
3. 데코레이터(Decorator)
def factorial1(num):
result = 1
for i in range(1, num+1):
result *= i
return result
factorial1(5)
def factorial2(num):
if (num < 1):
return 1
return num * factorial2(num - 1)
factorial2(5)
def time_checker(callback, num):
start = time.time()
result = callback(num)
end = time.time()
print("총 소요 시간: " , end - start)
return result
print('결과 값 : ', time_checker(factorial2, 10))
def time_checker2(callback):
def wrapper(num):
start = time.time()
result = callback(num)
end = time.time()
print('소요 시간 : ', end - start)
return result
return wrapper
@time_checker2
def factorial2(num):
if (num < 1):
return 1
return num * factorial2(num - 1)
factorial2(10)
@time_checker2
def add(num1, num2):
return num1+num2
print(add(10, 20))
def time_checker2(callback):
def wrapper(*args):
start = time.time()
result = callback(*args)
end = time.time()
print('소요 시간 : ', end - start)
return result
return wrapper
def time_checker2(callback):
def wrapper(*args, **kwargs):
start = time.time()
result = callback(*args, **kwargs)
end = time.time()
print('소요 시간 : ', end - start)
return result
return wrapper
DQ
def add() : pass