ETC
Nested Function / First-class Function / Closure Function
StoneSeller
2022. 4. 14. 22:47
중첩 함수 (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