Python

[전문가를 위한 파이썬] 5장 일급 함수 내용 정리

나쁜도비 2024. 5. 29. 20:52

일급 객체의 조건

- 런타임에 생성할 수 있다.

- 데이터 구조체의 변수나 요소에 할당할 수 있다.

- 함수 인수로 전달할 수 있다.

- 함수 결과로 반환할 수 있다.

 

5.1. 함수를 객체처럼 다루기

- __doc__: 객체의 도움말 텍스트 출력

def factorial(n):
	"""returns n!"""
    return 1 if n < 2 else n * factorial(n-1)
    
fact = factorial
fact(5) # 120

map(factorial, range(11))

list(map(fact, range(11)))

- 함수를 변수에 할당할 수 있다.

- map()의 인수로도 전달할 수 있다.

- 일급 함수가 있으면 함수형 스타일로 프로그래밍할 수 있다.

 

5.2. 고위 함수

- 고위함수(high-order function): 함수를 인수로 받거나, 함수를 결과로 반환하는 함수

- 대표적으로 map(), sort(), sorted()가 있음.

 

5.2.1. map(), filter(), reduce()의 대안

- 함수형 언어는 모두 map(), filter(), reduce() 고위함수를 제공한다.

- 지능형 리스트나 제너레이터 표현식으로 map(), filter() 조합이 처리하는 작업을 표현할 수 있다.

 

 

5.3. 익명 함수

- lambda 키워드는 파이썬 표현식 내에 익명함수를 생성한다.

 

 

5.4. 일곱 가지 맛의 콜러블 객체

- 호출 연산자인 ()는 사용자 정의 함수 이외의 다른 객체에도 적용할 수 있다.

- 호출할 수 있는 객체인지 알아보려면 callable() 내장 함수를 사용한다.

- 콜러블의 종류

1. 사용자 정의 함수: def 문이나 람다 표현식으로 생성한다.

2. 내장 함수: len()이나 time.strftime() 처럼 C언어로 구현된 함수(CPython의 경우)

3. 내장 메서드: dict.get() 처럼 C언어로 구현된 메서드

4. 메서드: 클래스 본체에 정의된 함수

5. 클래스: 호출될 때 클래스는 자신의 __new__() 메서드를 실행해서 객체를 생성하고, __init__()으로 초기화한 후, 최종적으로 호출자에 객체를 반환한다.

6. 클래스 객체: 클래스가 __call__() 메서드를 구현하려면 이 클래스의 객체는 함수로 호출될 수 있다.

7. 제너레이터 함수: yield 키워드를 사용하는 함수나 메서드. 이 함수가 호출되면 제너레이터 객체를 반환한다.

 

 

5.5. 사용자 정의 콜러블형

- 파이썬 함수가 실제 객체일 뿐만 아니라, 모든 파이썬 객체가 함수처럼 동작하게 만들 수 있다. __call__() 인스턴스 메서드를 구현하면 된다.

import random

class BingoCage:
	def __init__(self, items):
    	self._items = list(items) 
        random.shuffle(self._items)
        
    def pick(self): # 핵심 메서드
    	try:
        	return self._items.pop()
        except IndexError:
        	raise LookupError("pick from empty BingoCage")
    
    def __call__(self): # bingo.pick()에 대한 단축 형태로 bingo()를 정의함.
    	return self.pick()
        
	
bingo = BingoCage(range(3))
bingo.pick()
# 1

bingo()
# 0

- BingoCage의 경우 객체를 함수처럼 호출할 때마다 항목을 하나 꺼낸 후 변경된 상태를 유지해야 하는데, __call__() 메서드를 구현하면 이런 객체를 생성하기 쉽다.

- 이러한 예로 데코레이더가 있는데, 데코레이터는 함수이지만 때때로 호출된 후의 상태를 기억할 수 있는 기능이 유용하게 사용된다.

 

 

5.6. 함수 인트로스펙션

- __dict__ 속성: 함수는 객체에 할당된 사용자 속성을 __dict__ 속성을 이용해 보관한다.

 

 

5.7. 위치 매개변수에서 키워드 전용 매개변수까지

- 함수를 정의할 때 키워드 전용 인수(keyword-only argument)를 지정하려면 *가 붙은 인수 뒤에 이름을 지정한다.

 

 

5.8. 매개변수에 대한 정보 읽기

import bobo

@bobo.query("/")
def hello(person):
	return "Hello %s!" % person


- bobo.query() 데커레이터는 hello()와 같은 평범한 함수와 프레임워크에서 제공하는 요청처리 메커니즘을 결합시킨다.

- bobo가 hello() 함수의 내부를 조사해서 person이라는 매개변수가 필요하다는 것을 알아내기 때문에, 프로그래머는 요청 객체를 건드릴 필요가 없다.

- 함수 객체 안의 __defaults__ 속성에는 위치(positional) 인수와 키워드 인수의 기본값을 가진 튜플이 들어있다. 

def clip(text, max_len=80):
	a = 1
    b = 2
    return a + b
    
clip.__defaults__ # (80, )

clip.__code__co.varnames # ('text', 'max_len', 'a', 'b')

clip.__code__.co_argcount # 2

 

 

5.9. 함수 애너테이션

- 함수 선언에서 각 매개변수에는 : 뒤에 애너테이션 표현식을 추가할 수 있다. 

- 애너테이션은 전혀 처리되지 않으며, 단지 함수 객체 안의 dict형 __annotations__속성에 저장될 뿐이다.

 

 

5.10. 함수형 프로그래밍을 위한 패키지

5.10.1. operator 모듈

from functools import reduce
from operator import mul

def fact(n):
	return reduce(mul, range(1, n+1))

 

5.10.2. functools.partial() 인수로 고정하기

- functools.partial()은 함수를 부분적으로 실행할 수 있게 해주는 고위함수이다.

from operator import mul
from functools import partial

triple = partial(mul, 3)
triple(7) # 21

 

5.11. 요약

- 파이썬 함수의 일급 특성의 기본 개념은 함수를 변수에 할당하고, 다른 함수에 전달하고, 데이터 구조체에 저장하며, 함수 속성에 접근해서 프레임워크나 도구가 이 속성 정보를 사용할 수 있게 해주는 것이다.

- 고위함수의 예로 sorted(), min(), max(), functools.partial()이 있다.

- 파이썬에서 콜러블은 람다, __call__() 메서드를 구현하는 클래스 객체 등이 있다. 모든 콜러블은 callable() 내장함수가 탐지할 수 있다.

- functools.partial(), operator 모듈은 함수형 프로그래밍을 할 수 있게 해준다.

 


딥러닝에서의 일급 함수 예제

https://colab.research.google.com/drive/1paES-cqaKEcAJ29A7aNnqptnBwAm2Qh4#scrollTo=awMOCKXLPoJx

728x90