본문 바로가기

프로그래밍/파이썬

[파이썬] 일등 함수(first-class citizen) 이란?

일등함수

함수는 일등 시민(first-class citizen)

일등 시민(first-class citizen)이라고? 정말 생소한 개념이다.
익숙하진 않지만, 다음 조건을 충족한다면 일등 시민이라고 할 수 있다.

  • 변수나 데이터에 할당 할 수 있어야 한다.

  • 객체의 인자로 넘길 수 있어야 한다.

  • 객체의 리턴값으로 리턴 할 수 있어야 한다.

위키백과 : 일급 객체란?

엥? 그거 다 되는거 아니야? 싶겠지만 파이썬에서는 독특하게도 함수도 위와 같은 기능을 수행한다.

이러한 특징을 가진 일급 객체(first-class citizen)를 사용하면 손쉽게 함수를 재활용 할 수 있다.

예제참고 블로그

1. 함수를 변수에 할당 가능

def square(x) :
  return x * x
 
f1 = square_numbers # f1이라는 '변수'에 함수를 할당! 
f2 = square_numbers(5)

괄호를 붙이고 안붙이고 차이를 알아야 한다.
괄화를 안 붙이면 그 자체이지만 괄호를 붙이면 함수가 돌려주는 리턴값을 의미한다.

print(id(square)id(f1))을 출력해보자.

square :  <function square at 0x7f863832fbf8>
 f1 :  <function square at 0x7f863832fbf8>

2. 함수를 함수의 인자로 전달 가능

def square(x):
    return x ** 2
 
def my_func(func, arg_list):
    result = []
    for i in arg_lists:
        result.append(func(i)) # func()는 함수를 호출한 '결과(return)' 값을 얻는다.   
                &nbnbsp;              # 여기서 얻어진 값들을 빈 result 리스트에 넣는다. 
 
num_list = [1, 2, 3]
squares = my_func(squarenum_list) # square 함수를 인자(argument)로 해서 전달한다! 
 
print(squares)
 
>>> 출력결과
[1, 4, 9]

먄악, 함수를 인자로 전달하는 기능이 없다면 중복되는 코드가 많이 발생한다. 아마 아래처럼.

def square(arg_list):
    result = []
    for i in arg_list:
        result.append(i*i)
    return result
 
def cub(arg_list):
    result = []
    for i in arg_list:
        result.append(i*i*i)
    return result

3. 함수를 다른 함수 내에서 정의 가능 (4번에서 같이 살펴보자)

4. 함수의 결과값으로 또 다른 함수를 리턴 가능

처음 보면 이해하기 힘들다. 차근차근 살펴보자.

# 1급 객체의 특징 : 함수를 리턴할 수 있다. 
 
def log(msg): #1 , #3 
    def log_message(): #4, #10 
        print("Log : "msg) #11 
 
    return log_message #5 
 
log_hi = log("Hello Everybody") #2, #6 
print(log_hi) #6 #7 
log_hi() #9 
 
>>> 출력결과
<function log.<locals>.log_message at 0x7f8638260c80> #8 
Log :  Hello Everybody #11 
  1. 인터프리터의 해석 순서대로 # 번호를 따라간다.

  2. #2번에서 log함수의 리턴값을 log_message라는 '변수'에 할당하고 있다.

  3. log 함수가 어떻게 생겨먹는지 보러가자. #3번에 있다.

  4. log_message 함수를 정의해주고 #4에서 #5로 넘어간다. 무언가를 리턴해주고 있다.

  5. log_message가 어떻게 생겨먹었는지 #6에서 프린트로 찍어보자

  6. #8를 살펴보면 뭔진 모르겠는데 아무튼 function이 출력된다.

  7. 아~~까 #2번에서 할당한 값이 함수(function)이라니! 한번 함수를 실행해보자

  8. #9번에서 실행해보고 있다.

  9. 이제서야 #10으로 간다.

  10. 마지막 #11에서 msg를 출력한다

    • 근데, msg는 어디서 났지? log_message 함수에는 msg라는 파라미터가 전달된 적 없는데?

    • log_message()와 같은 함수를 클로저(closure) 함수라고 한다.

    • 클로져(closure) 함수는 #1번의 log함수가 종료되더라도, 지역변수를 기억하고 있는다.