파이썬 특수 문법(데코레이터, 이터레이터등) - . First-class function

16. First-class function

First-class 함수: 함수 자체를 인자로 다른 함수에 전달, 다른 함수의 결과값으로 리턴, 함수를 변수에 할당할 수 있는 함수

  • 사실 파이썬에서는 모든 것이 객체!
  • 파이썬 함수도 객체로 되어 있어서, 기본 함수 기능 이외 객체와 같은 활용이 가능 (파이썬의 함수들은 First-class 함수로 사용 가능)

  • 지금까지 배운 언어의 맥락과는 뿌리가 다른 사고 - 함수형 프로그래밍에서부터 고안된 기법

16.1. 다른 변수에 함수 할당 가능

In [6]:
def calc_square(digit):
    return digit * digit
In [7]:
calc_square(2)
Out[7]:
4
In [11]:
# 1. func1 이라는 변수에 함수를 할당 가능
func1 = calc_square
In [12]:
print (calc_square)
<function calc_square at 0x10b459598>
In [13]:
func1(2)
Out[13]:
4

16.2. 함수가 할당된 변수는 동일한 함수처럼 활용 가능

In [14]:
# 2. func1 이라는 변수는 calc_square 함수를 가리키고, calc_square 와 마찬가지로 인자도 넣어서 결과도 얻을 수 있음 (완전 calc_square와 동일)
print (func1)
func1(2)
<function calc_square at 0x10b459598>
Out[14]:
4
In [16]:
class MyClass:
    def my_class(self):
        print ('안녕')
        pass

object1 = MyClass()
my_class1 = object1.my_class
my_class1()
안녕

16.3. 함수를 다른 함수에 인자로 넣을 수도 있음

In [17]:
def calc_square(digit):
    return digit * digit

def calc_plus(digit):
    return digit + digit

def calc_quad(digit):
    return digit * digit * digit * digit
In [19]:
def list_square(function, digit_list):
    result = list()
    for digit in digit_list:
        result.append(function(digit)) 
    print (result)
In [20]:
num_list = [1, 2, 3, 4, 5]
In [22]:
list_square(calc_square, num_list)
list_square(calc_plus, num_list)
list_square(calc_quad, num_list)
[1, 4, 9, 16, 25]
[2, 4, 6, 8, 10]
[1, 16, 81, 256, 625]
In [21]:
num_list_square
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-21-8684ab0f61db> in <module>()
----> 1 num_list_square

NameError: name 'num_list_square' is not defined

16.4. 함수의 결과값으로 함수를 리턴할 수도 있음1

In [27]:
def logger(msg):
    message = msg
    def msg_creator():    # <--- 함수 안에 함수를 만들 수도 있음
        print ('[HIGH LEVEL]: ', message)
    return msg_creator
In [28]:
log1 = logger('Dave Log-in')
In [29]:
print(log1)
<function logger.<locals>.msg_creator at 0x10b459378>
In [30]:
log1()
[HIGH LEVEL]:  Dave Log-in
복습
1. 함수 안에 선언된 변수를 칭하는 용어는?
2. 함수 안에 선언된 변수 값이 유지되는 기간은?
3. 위 코드에서 log1() 결과값에서 특이한 점은?

아예 logger 함수를 통째로 삭제해도 log1() 함수는 logger 함수 안에 있는 msg_creator 함수와 msg 값을 유지

In [31]:
del logger
In [32]:
log1()
[HIGH LEVEL]:  Dave Log-in

16.5. 함수의 결과값으로 함수를 리턴할 수도 있음2

In [33]:
def html_creator(tag):
    def text_wrapper(msg):
        print ('<{0}>{1}<{0}>'.format(tag, msg))
    return text_wrapper
In [34]:
h1_html_creator = html_creator('h1') #1
print (h1_html_creator)
<function html_creator.<locals>.text_wrapper at 0x10b4586a8>
In [35]:
h1_html_creator('H1 태그는 타이틀을 표시하는 태그입니다.')
<h1>H1 태그는 타이틀을 표시하는 태그입니다.<h1>
In [36]:
p_html_creator = html_creator('p')
p_html_creator('P 태그는 문단을 표시하는 태그입니다.')
<p>P 태그는 문단을 표시하는 태그입니다.<p>
생각해보기
위와 같이 출력되는 이유를 생각해봅니다.
초간단 연습2
스트링으로 된 문자열이 주어지면, 정해진 목차 기호로 나열해주는 First-class 함수를 만들어보세요
예: 
func1 = index_creator('-')
func1(list_data)

출력:
* ....
* ....
* ....
In [79]:
def list_creator(tag):
    def text_wrapper(msg):
        print ('{0} {1}'.format(tag, msg))
    return text_wrapper

data_list_minus = list_creator('-')
data_list_minus('안녕')

data_list_mul = list_creator('*')
data_list_mul('안녕')

data_list_x = list_creator('X')
data_list_x('안녕')
<class 'function'>
- 안녕
* 안녕
X 안녕
도전 과제
위에서 만든 First-class 함수로 네이버 실시간 키워드를 리스트로 출력해보세요
In [43]:
import requests
from bs4 import BeautifulSoup

res = requests.get('https://www.naver.com/')
soup = BeautifulSoup(res.content, 'html.parser')
# a 태그이면서 href 속성 값이 특정한 값을 갖는 경우 탐색
link_title = soup.select("#PM_ID_ct > div.header > div.section_navbar > div.area_hotkeyword.PM_CL_realtimeKeyword_base > div.ah_roll.PM_CL_realtimeKeyword_rolling_base > div > ul > li")
for num in range(len(link_title)):
    # link_title 은 리스트 타입으로 개별 태그셋을 저장합니다.
    # print(type(link_title))
    # 각 태그셋은 string이 아니라 BeautifulSoup의 element.Tag 라는 객체입니다.
    # print(type(link_title[0]))
    # 그래서 각 태그셋에 다시 find(), find_all() 과 같은 BeautifulSoup 메서드를 사용할 수 있음을 확인할 수 있습니다.
    link_title_each = link_title[num].find_all('span')
    data_list_minus(link_title_each[1].get_text())
- 이시영
- 모유비누
- 정일우
- 유아인
- 조민기 빈소
- 나경원
- 김하온
- 승리
- 그루비룸
- sbs골프
- 조민기 유서
- k리그
- 미세먼지
- 착한마녀전
- 박서준
- 현대자동차 채용
- 사라진밤
- 메가박스
- 영화순위
- 2018 3월 모의고사 등급컷