본문 바로가기

진리는어디에/Python

[Python] 함수 #6 일급 객체(first class object)

상상속의 퍼스트 클래스 이미지

이번 포스트에서는 일급 객체(first class object)라는 용어에 대해 살펴 보겠다. 개념적인 내용이므로 프로그래밍하는데 큰 영향을 끼치지는 않지만(특히 파이썬에서), 알아 두면 어디 가서 아는척하기 좋은 지식이니 가볍게 읽고 넘어가도록 하자.

목차

  1. 함수 소개
  2. 디폴트 파라미터 주의 사항
  3. 파라미터 언패킹
  4. 파라미터 패킹
  5. 함수 객체
  6. >> 일급 객체(first class object)
  7. 람다(lambda)

일급 객체(first class object)란?

우리가 프로그래밍을 하다 보면 first class object(일급 객체)라는 다소 생소한 용어를 만날 수 있다. 일급 객체란 프로그래밍에서 아래에 나열된 특징을 가지는 모든 객체들을 가리킨다.

  • 모든 요소는 "할당 명령문의 대상"이 될 수 있다.
  • 모든 요소는 "동일(equal, ==) 비교의 대상"이 될 수 있다.
  • 모든 요소는 "함수의 파라미터"가 될 수 있다.
  • 모든 요소는 "함수의 반환 값"이 될 수 있다.

우리가 이미 알고 있는 int, float, str 타입의 모든 객체는 일급 객체라고 볼 수 있다. 앞에 언급된 타입의 객체들은 함수의 인자(파라미터)로 쓰일 수 있고, 함수의 반환으로도 사용 가능하며, 할당 할 수 있고, 비교 연산도 가능하다. 이런 연산이 가능한 객체들을 일급 객체라고 정의한다.

파이썬에서는 "함수도 일급 객체"다

갑자기 일급 객체 이야기를 꺼낸 것은, 파이썬에서는 함수도 일급 객체로 취급 된다는 것을 알려주기 위함이다. 이전 [함수 객체] 포스트에서 파이썬에서 함수는 객체이며, 함수의 이름은 함수 객체를 가리키는 참조 변수라고 했다. 그리고 함수의 이름을 이용해 아래의 연산들이 가능하다.

def foo() :
    print('foo')

def bar(f) :
    f()

f = foo         # 할당 명령문의 대상이 될 수 있다

print(f is foo) # 동일(equal) 비교의 대상이 될 수 있다.
    
bar(foo)        # 함수의 파라미터가 될 수 있다

def con() :     # 함수의 반환 값이 될 수 있다
    return foo

con()()

함수의 이름을 다른 변수에 할당하는 것도 가능하고, 비교 또한 가능하다. 또한 다른 함수의 인자로써 함수를 사용하는 것도 가능하고, 함수의 리턴 값으로 함수를 사용하는 것도 가능하다. 일급 객체가 정의하는 모든 연산들이 파이썬 함수를 이용해 가능하다.

파이썬에선 함수도 일급 객체(first class object)다.

함수가 일급 객체로써 사용되면 무엇이 달라지기에 이런 이야기를 꺼냈을까?

일급 객체로 취급 된다는 것은 다른 함수의 인자로써 사용 가능하다는 이야기고, 입력 받은 자료형의 각 요소들을 일괄적으로 처리하여 iterator 객체로 리턴하는 map과 같은 함수(사실은 객체)의 인자로 사용 가능하다는 뜻이다.

아래에서 함수를 인자로 사용하는 간단한 map 예제를 살펴 보도록 하자. map은 인자로 넘어 오는 리스트의 모든 요소들을 역시 인자로 같이 넘어 온 "함수"를 이용해 처리하여 iterator 형태로 반환 한다. 보통 여러 개의 데이터를 한번에 다른 형태로 변경하기 위해 사용된다.

# 리스트 s의 모든 요소에 제곱값을 가지는 새로운 리스트 생성 예제
s = [1, 2, 3, 4, 5]

# 1. 일반 파이썬 프로그래밍
def make_square(s) :
    r = []
    for i in s :
        r.append(i * i)
    return r

for i in make_square(s) :
    print(i, end=' ')
print()

# 2. 함수를 일급 객체로 취급하는 map을 이용한 프로그래밍    
def square(x) :
    return x * x

m = map(square, s)    # map 객체는 함수, 리스트를 보관

for i in m :
    print(i, end=' ')
print()

make_square 함수의 복잡한 작업이, 짧은 square 함수를 만들고 map()에 넘겨주는 것만으로 동일한 결과를 얻을 수 있다. 함수를 일급 객체로 사용하는 경우 위와 같은 프로그래밍이 가능하다. map과 같은 함수(사실은 객체다)를 사용하면 게으른 연산이라고 하여 메모리와 계산을 필요 할 때만 하는 성능적으로 유리한면이 있는데 지금 단계에서는 어려운 내용이므로, 성능상 이점이 있다 정도로만 이해하고 넘어가도록 한다.

하지만

이 포스트의 제일 처음에 필자가 프로그래밍에 큰 영향을 끼치지 않는다고 이야기 했다. 왜나면 위와 같은 작업은 우리가 이전에 배웠던 지능형 리스트를 이용하면 더 간단하고 편리하게 처리 할 수 있기 때문이다.

s = [1, 2, 3, 4, 5]

r = [x * x for x in s]
for i in r :
    print(i, end=' ')
print()

위 코드의 내용은 리스트 s를 순회하며 각 요소 x를 제곱한 결과들의 리스트 r을 만든다는 뜻이다. 지능형 리스트의 자세한 사항은 [여기]를 참고하도록 하자.

마치며

우리가 프로그래밍을 하면서 한번은 마주칠 수 있는 '일급 객체'라는 용어에 대해 알아보고, 파이썬의 함수는 일급 객체로써 취급 되기 때문에 다른 함수의 인자로 사용될 수 있다는 것을 알아 보았다.

파이썬에서는 다양한 프로그래밍 기법들에서 함수를 인자로써 이용하고 있으므로, 다른 것은 가벼게 읽고 넘어 가더라도 함수가 일급 객체로 취급 된다는 것은 꼭 이해하고 넘어가자.

다음 장에서는 람다(lambda) 함수에 대해 알아 보도록 하겠다.

부록 1. 같이 보면 좋은 글

 

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!