[python] 일급함수(First-class function)

728x90

일급 함수(first-class function)는 프로그래밍 언어의 일급 객체(first-class object)로서의 특성을 가진 함수를 말합니다. 일급 객체의 특성은 다음과 같습니다

 

1. 실행시 런타임 초기화를 해야 합니다.
2. 변수로 할당 가능해야 합니다.
3. 함수 인수 전달 가능해야합니다.
4. 함수 결과가 반환 가능(return)해야 합니다.

 

 

먼저 하나의 함수와 하나의 클래스를 만들어 보겠습니다.

def factorial(n):
    '''팩토리얼 함수. n:int'''
    if n == 1:
        return 1
    return n*factorial(n-1)

class A:
    pass

 

이때 factorial은 함수이고 A는 클래스입니다.

 

이 두개의 타입을 확인해보겠습니다.

print(type(factorial),type(A)) #출력: <class 'function'> <class 'type'>

 

위 결과를 보면 두개 모두 클래스로 취급됩니다.

 

여기서 함수만 가지고 있는 기능을 출력해보겠습니다.

print(set(sorted(dir(factorial))) - set(sorted(dir(A)))) 
#출력: {'__annotations__', '__name__', '__call__', '__globals__', '__qualname__', '__defaults__', '__kwdefaults__', '__get__', '__code__', '__closure__'}

 

1. 런타임 초기화

print(factorial(5)) # 출력: 120
print(factorial(10)) #출력: 3628800

위 예제를 보면 함수를 실행할때 마다 초기화가 되고 새로운 인자가 적용되어 값이 출력되는 것을 확인할 수 있습니다.

 

2. 변수 할당

# 변수할당
fuc = factorial
print(fuc) #출력: <function factorial at 0x000002B3F96BDF70>
print(fuc(5)) #출력: 120
print(fuc(10)) #출력: 3628800
print(list(map(fuc,range(1,11)))) # 출력: [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

 

위 예제에서 factorial 함수를 fuc라는 변수에 할당하였고, 변수를 함수와 동일하게 사용할 수 있는 것을 확인할 수 있습니다.

 

3. 함수 인수 전달 및 함수로 결과 반환 -> 고위함수

# map, filter, reduce

print(map(fuc,filter(lambda x:x%2, range(1,6)))) #출력: <map object at 0x000001FE0AC0B820>
print(list(map(fuc,filter(lambda x:x%2, range(1,6))))) #출력: [1, 6, 120]
print([fuc(i) for i in range(1,6) if i % 2]) #출력: [1, 6, 120]

from functools import reduce
from operator import add

print(add,range(1,11))
print(reduce(add,range(1,11))) # reduce는 감소 add는 더함 -> 1~11까지 하나하나 더해가면서 인자를 하나씩 없앰. 결과값 : 55
print(sum((range(1,11)))) # 출력: 55

 

4. 익명함수(lambda)

익명함수(lambda)는 가급적 아래 사항들을 권장하고 있습니다.

1) 주석 작성

2) 함수작성

3) 일반함수 형태로 리팩토링 권장

print(reduce(lambda x,t: x+t, range(1,11))) # 출력: 55

5. 호출연산자(collable)

호출연산자란 메소드 형태로 호출가능한지를 확인하는 함수입니다.

print(callable(str)) #출력 : True
print(callable(A)) #출력 : True
print(callable(fuc)) #출력 : True
print(callable(3.14)) #출력 : False -> 3.14는 함수가 아니기 때문에 호출불가

6. partial()

partial은 인수를 고정하는 메서드입니다. 주로 콜백함수에 사용합니다.

from operator import mul
from functools import partial

print(mul(10,10)) #출력: 100

# 인수고정
five = partial(mul,5) # 한쪽의 인수를 5로 고정 -> 5x?가 된다
print(five(10)) #출력: 50 = 5x10

print(five(500)) #출력: 2500 = 5x500

six = partial(five,6)
print(six()) #출력: 30 = 5x6 ->두개의 값이 고정됨 -> mul은 두개의 인자를 받기 때문에 six변수안에 매개변수를 넣을 수 없다
# print(six(3)) # TypeError: mul expected 2 arguments, got 3

print([five(i) for i in range(1,11)]) #출력 : [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
print(list(map(five,range(1,11)))) #출력 : [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
print(reduce(add,[five(i) for i in range(1,11)])) #출력: 275