본문 바로가기
AI 공부/파이썬

파이썬 (함수 - 2) 람다함수, 콜백함수, map함수, Closure, Decorator

by AI Sonny 2022. 8. 2.
728x90

람다함수 (lambda) 란?

  • 한줄 짜리 간단한 함수를 만들 때 사용
  • 1회용 함수를 만들 때 많이 사용 (휘발성 한번 함수 안 변수에서 사용하면 함수 내에서 사라짐)
  • 람다 함수는 아주 간단한 파라미터가 정의되거나 반환하는 함수일 경우 사용

 

def add(num1,num2):
    return num1+num2
add(1,2)

↓↓↓↓↓↓↓람다함수 사용↓↓↓↓↓↓↓↓

add_lambda = lambda num1, num2: num1+num2   # 함수도 객체다!(파이썬은 다 객체이다.)
add_lambda(1,2)

 

람다함수는 쉽게 말해 기존 함수 구조를 줄여 놓은 것이라 보면된다.

 

구조를 보면 기존 변수가 람다 뒤에 나오고, 리턴값이 바로 옆에 나오게 된다.

 

def get_even(lst):
    result = []
    for n in lst:
        if n % 2 == 0:
            result.append(n)
    return result

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓람다함수 전환↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

get_even = lambda lst: [i for i in lst if i % 2 == 0]   # 컴프리헨션 생각을 못함
get_even([1,2,3,4])

 

그리고 람다함수도 컴프리헨션이 가능하다...

 


클로져 (Closure) 란?

  • 함수 안에 함수(내부함수)를 만드는 것
  • 함수를 둘러싼 상태(외부의 지역변수)를 기억하고 있다가, 내부함수를 실행할 때 기억한 지역변수를 처리한다.

 

def do_outer(a,b):
    def do_inner(): # 내부함수 입장에서 외부함수 지역변수와 파라미터 접근 가능!
        return a+b
    return do_inner # 내부함수의 주소를 반환
inner_result1 = do_outer(10,20) # 값을 갖고 있는 형태(class와 동일)!!!!
inner_result2 = do_outer(30,50)
print(inner_result1,inner_result2)  # 주소가 다르다

=> <0x7faa37f559e0> <0x7faa37f55ef0>

 

다음 구조를 보면 함수가 2번 나오게 된다. outer가 외부함수, inner가 내부함수이다.

 

내부함수는 외부함수의 지역변수와 파라미터의 접근이 가능하지만,

 

외부함수는 내부함수의 지역변수와 파라미터의 접근이 불가능하다.

 


콜백함수란?

  • 함수의 인자로 사용되는 함수를 말한다. 
  • 두수를 인자로 받아 더하는 함수와 빼는 함수를 만든다고 가정
  • 두개의 함수 모두 실수가 들어올 경우 정수로 변경해야하는 공통 기능이 있어야한다고 가정
  • 실수를 정수로 변경하는 공통기능은 어떠한 함수에 구현

 

- 예시 문제

 

조건 1) 실수를 정수로 변경하는 공통기능을 어떠한 함수에 구현해야 한다.

 

조건 2) 그래서 이 어떠한 함수에 인자로 더하는 함수와 빼는 함수를 넣어서 더하는 처리와 빼는 처리를 하면?

 

def convert_int(cb,a,b):  # cb = callback(함수를 인자로 받음)
    # 공통기능 부분
    a = int(a)
    b = int(b)
    return cb(a,b) # 인자로 받은 콜백함수를 실행하여 결과값을 반환!!

 

다음과 같이 코딩하여 조건 1을 만족하는 함수를 만들었다.

 

def add_func(num1,num2):
    return num1+num2
def sub_func(num1,num2):
    return num1-num2

convert_int(add_func,11.5,20.222) # add_func이 콜백함수!
convert_int(sub_func,11.5,20.222) # add_func이 콜백함수!

=>	30
	-9

 

이 후 더하기, 빼기 함수 2개를 생성하였고, convert_int 안에 넣었다.

 

이로써 콜백되어 11.5와 20.222는 정수로 변환되었고, 곱하기와 빼기가 되어 값이 출력된다.

 


map 함수란?

 

map 함수는 두번째 인자로 들어온 반복 가능한 자료형 (리스트나 튜플)을 첫번째 인자로 들어온

 

함수에 하나씩 집어넣어 함수를 수행한다.

 

기본적인 구조는 map(function, iterable)이며, map 함수의 반환값을 출력하고 싶으면 list나 tuple로 변환해야 한다.

 

그렇기 때문에 처음 매개변수로는 함수가 오고, 두번째 매개변수로는 반복 가능한 자료형(리스트, 튜플 등)이 온다.

 

쉽게 말해 map(적용시킬 함수, 적용할 값들)이라 볼 수 있다. map함수를 람다함수와 섞어보겠다.

 

map_obj = map(lambda x: x**0.5, range(2,10))
map_obj

=> <map at 0x7faa37f964d0>

 

map함수는 주소값을 출력한다. 그래서 값출력을 원할시 list를 씌워주면 값이 나오게 된다.

 

list(map_obj) # 두번 실행하면 사라짐!

=>	[1.4142135623730951,
 	1.7320508075688772,
 	2.0,
 	2.23606797749979,
 	2.449489742783178,
 	2.6457513110645907,
 	2.8284271247461903,
 	3.0]

 

그리고 map함수는 2번 실행하게 되면 신기하게도 값이 사라지는 특징을 볼 수 있다.

 


Decorator (장식하다. 꾸미다.) 란?

  • 코드를 변경하지 않고 기능을 추가하거나 수정하고 싶을 때 정의하는 표현식
  • 내부함수의 주소를 리턴하는 클로져와 비슷하고 함수를 다른함수의 인자로 전달하는 방식과 비슷하다.
  • 두가지 방식을 합친 것과 같다.
  • 코딩한 시간을 넣거나 할 때 사용한다.

데코레이터는 코딩의 내가 했던 시간 등 꾸밀 때 필요한 것으로 구조는 다음과 같다.

 

def decorator_func(org_func): # 함수를 인자로 받는다.
    def wrapper_func(): # 내부함수를 구현한다.
        print("org_func 가 실행 되기 전입니다.")
        org_func()  # org_func 함수를 실행 (영향을 받지 않는다.)
    return wrapper_func # 내부함수의 주소만 반환

@decorator_func # == decorator_func(do_func)
def do_func():
    print("original 함수가 실행 되었습니다.")

result = decorator_func(do_func)    # 데코레이터 함수에 감싸고자하는 함수의 주소를 인자로 넣는다.
result()    # wrapper_func() -> 그 안에 코드가 실행된다. -> 인자로 받은 함수가 실행된다.

=>	org_func 가 실행 되기 전입니다.
	original 함수가 실행 되었습니다.

 

처음에 내부함수를 만들어 본인이 데코하고자 하는 것을 넣어 내부함수를 구현하고,

외부에 데코할 함수를 만들고, 파라미터를 내부함수의 함수로 넣는다.

 

이 후 내가 만든 함수를 실행하면 따로 코드를 변경하지 않고, 기능을 추가할 수 있다.

 

그리고 데코를 선언하는 방법은 위와 같이 @와 def가 있다.

 


오늘은 점심먹고, 강사님이 내주신 문제를 풀었는데 2시간 동안  문제 2개를 겨우 풀었다.

 

배열쪽에 개념이 많이 부족하니 보충을 해야할 것 같다.

728x90

댓글