새소식

ETC

Nested Function / First-class Function / Closure Function

  • -

중첩 함수 (Nested function)

  • 함수 내부에 정의된 함수
  • 중첩 함수는 해당 함수가 정의된 함수 내에서 호출 및 변환 가능
  • 중첩 함수는 함수 밖에서는 호출 불가
    함수 안에 선언된 변수는 함수 안에서만 사용 가능한 원리와 동일(로컬 변수)
def outer_func():
    print("outer_function")
    
    # nested function 정의
    def inner_func():
        return "inner_function"
    print(inner_func())

outer_func()
output
outer_function
inner_function

 

중첩 함수를 정의된 함수 밖에서 따로 호출할 수 없다.

inner_func()
output
NameError: name 'inner_func' is not defined​

 

 


First-class function

  • 함수 자체를 변수에 저장 가능
  • 함수의 인자에 다른 함수를 인수로 전달 가능
  • return 값으로 함수를 전달 가능

파이썬에서는 모든 것이 객체이다.
파이썬 함수도 객체로 되어 있어서 파이썬의 함수들은 First-class function으로 사용 가능하다.

 

1. 함수 자체를 변수에 저장 가능

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

>>> def add(a,b):
>>>    return a + b

>>> test1 = add
>>> test1(2,3)

5

 

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

def list_square(func, digit_list):
    result = list()
    for digit in digit_list:
        result.append(func(digit))
    print(result)

def square(a):
    return a * a
    
num_list = [1,2,3]

list_square(square, num_list)
output
[1, 4, 9]​

 

3. 함수의 결과값으로 함수를 반환 가능

이렇게 함수의 결과값으로 중첩 함수를 반환하면 그 함수 밖에서도 중첩 함수를 호출할 수 있다.

def index_creator(tag):
    def text_wrapper(string):
        print(f'{tag} {string}')
    return text_wrapper

minus_tag = index_creator('-')
minus_tag('일기 쓰기')

mul_tag = index_creator('*')
mul_tag('알고리즘 공부')
output
- 일기 쓰기
* 알고리즘 공부

 

위에서 정의한 함수를 다음과 같이 이용할 수 있다.

블로그에서 title만을 가져오는데 앞에 '-' 태그를 붙인다.

import requests
from bs4 import BeautifulSoup

res= requests.get('https://life-is-also-pizza.tistory.com/')
soup = BeautifulSoup(res.content, 'html.parser')

link_titles = soup.select("div#mArticle > div.list_content strong")

for link_title in link_titles:
    minus_tag(link_title.get_text())
output
- 다중공선성
- MySQL_Foreign key
- MySQL 파일로 실행
- PyMySQL
- 트리_BOJ #2263: 트리의 순회
- 트리_BOJ #4256: 트리​

 


Closure function

  • 함수와 해당 함수가 갖고 있는 데이터를 복사, 저장해서 별도 함수로 활용하는 기법으로 First-class function과 동일
  • 외부 함수가 소멸되더라도, 외부 함수 안에 있는 로컬 변수 값과 중첩함수를 사용할 수 있다.

closure_func = outer_func(10) 에서 outer_func은 호출 종료

closure_func() 호출 시 inner_func을 호출

outer_func(10)은 호출 종료시 num 값이 없어지지만, closure_func()에서 inner_func이 호출되면서 이전의 num값인 10을 사용

 

심지어 outer_func을 삭제해버려도 inner_func과 num값은 closure_func에 살아있다.

def outer_func(num):
    def inner_func():
        print(num)
        return '종료'
    return inner_func

closure_func = outer_func(10)
closure_func()

# outer_func 삭제
del outer_func

closure_func()
output
10
'종료'

 

그렇다면 언제 Closure function을 사용하는가?

  • 일반적으로 제공해야 할 method가 적은 경우, closure을 사용하기도 한다.
  • 제공해야 할 method가 많은 경우는 class를 사용하여 구현
def calc_power(n):
    def power(digit):
        return digit ** n
    return power


# closure func들이 들어있는 리스트
func_list = []
for num in range(1,5):
    func_list.append(calc_power(num))

for func in func_list:
    print(func(2))
output
2
4
8
16​
728x90

'ETC' 카테고리의 다른 글

@staticmethod 데코레이터  (0) 2022.07.01
[Python] 매개 변수 & 변수 범위  (0) 2022.06.24
[Python] argparse  (0) 2022.06.22
[Python] 자료형  (0) 2022.06.21
@데코레이터  (0) 2022.04.15
Contents