Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 에러
- 오라클
- Git
- rdbms
- 파이썬
- database
- javascript
- mysql
- 스프링
- jQuery
- mybatis
- 백준
- 자바
- spring
- 링크
- 데이터베이스
- flask
- PYTHON
- 웹프로그래밍
- BOJ
- db
- TIL
- java
- 플라스크
- sql
- Oracle
- 이클립스
- 자바스크립트
- 알고리즘
- eclipse
Archives
- Today
- Total
기록과 정리의 공간
[Python] 클로저(Closure Function) 본문
1. 중첩 함수(Nested Function)
함수 내부에 정의된 또 다른 함수
중첩 함수는 해당 함수가 정의된 함수 내에서 호출 및 리턴이 가능하다.
함수 안에 선언된 변수(로컬 변수)는 함수 안에서만 사용 가능한 원리와 동일하다.
- 예시
def outer_func():
print("outer_func 호출됨")
def inner_func():
return "inner_func 호출됨"
print(inner_func())
outer_func()
"""
결과값 :
outer_func 호출됨
inner_func 호출됨
"""
- 중첩 함수를 함수 밖에서도 호출 할 수 있는 방법이 있다. (자세한 것은 2, 3번 참고)
def outer_func(num):
def inner_func():
print(num)
return "inner_func 호출 끝"
return inner_func
func = outer_func(10) # First-class function
print(func()) # Closure 호출
"""
결과값:
10
inner_func 호출 끝
"""
2. First-class 함수란?
- First-class함수란 아래와 같이 프로그래밍 언어가 함수를 first-class citizen으로 취급하는 것을 뜻 한다.
- 함수를 변수에 저장 할 수 있다.
- 함수의 인자에 다른 함수를 전달 할 수 있다.
- 함수의 리턴값으로 함수를 전달 할 수 있다.
- python에서는 모든 것이 객체이므로, python의 함수는 First-class함수로 사용이 가능하다.
- 참고로 이것은 함수형 프로그래밍에서 고안된 기법이다. python, GO, javascript, kotlin은 이를 지원한다.(c언어 등은 미지원)
- 예시1 : 함수를 변수에 할당하기
def calc_plus(n):
return n + n
func1 = calc_plus # func1이라는 변수에 위의 함수를 할당할 수 있다.
print(func1) # 결과값 : <function calc_plus at 0x0000024C2AD75310> (calc_plus함수를 가리킴)
print(func1(2)) # 결과값 : 4
- 예시2 : 함수를 다른 함수의 인자로 전달하기
def calc_plus(n):
return n + n
def calc_square(n):
return n * n
def calc_quad(n):
return n * n * n * n
def list_calc(func, num_list):
result = []
for num in num_list:
result.append(func(num))
print(result)
num_list = [1, 2, 3, 4]
list_calc(calc_plus, num_list) # 결과값 : [2, 4, 6, 8]
list_calc(calc_square, num_list) # 결과값 : [1, 4, 9, 16]
list_calc(calc_quad, num_list) # 결과값 : [1, 16, 81, 256]
- 예시3 : 함수의 리턴값으로 함수를 전달하기
def logger(msg):
def msg_creator():
print('생성 메시지 -', msg)
return msg_creator # 리턴값으로 함수 전달하기
func = logger("안녕하세요.")
func() # 결과값 : 생성 메시지 - 안녕하세요.
- First-class 함수 활용 예시
def html_creator(tag):
def text_wrapper(msg):
print ('<{0}>{1}</{0}>'.format(tag, msg))
return text_wrapper
h1_tag_creator = html_creator('h1')
h1_tag_creator("안녕") # 결과값 : <h1>안녕</h1>
p_tag_creator = html_creator('p')
p_tag_creator("안녕") # 결과값 : <p>안녕</p>
- 연습 문제1 : 아래와 같은 결과값이 출력되도록 First-class함수를 만들어보자.
# 결과값
- first
- second
- third
# 정답코드
def sign_creator(sign):
def input_text(text):
print('{0} {1}'.format(sign, text))
return input_text
hypen_creator = sign_creator('-')
text_list = ['first', 'second', 'third']
for text in text_list:
hypen_creator(text)
- 연습 문제2 : 크롤링을 이용해 링크의 '취미로 익히는 IT' 부분의 목록을 아래와 같은 형태로 출력해보자.
1. (왕초보) - 클래스 소개
2. (왕초보) - 블로그 개발 필요한 준비물 준비하기
3. (왕초보) - Github pages 설정해서 블로그 첫 페이지 만들어보기
4. (왕초보) - 초간단 페이지 만들어보기
5. (왕초보) - 이쁘게 테마 적용해보기
6. (왕초보) - 마크다운 기초 이해하고, 실제 나만의 블로그 페이지 만들기
7. (왕초보) - 다양한 마크다운 기법 익혀보며, 나만의 블로그 페이지 꾸며보기
import requests
from bs4 import BeautifulSoup
res = requests.get("https://davelee-fun.github.io/blog/crawl_html_css.html")
soup = BeautifulSoup(res.content, 'html.parser')
lecture_lists = soup.select('ul#hobby_course_list li')
def add_nums(num):
def get_lists(lists):
print("{0}. {1}".format(num, lists))
return get_lists
for i, list in enumerate(lecture_lists, start=1):
func = add_nums(i)
func(list.get_text())
3. Closure Function (클로저)
- 함수와 해당 함수가 가지고 있는 데이터를 함께 복사, 저장해서 별도의 함수로 사용하는 기법으로 First-class함수와 동일하다.
- 외부 함수가 소멸되더라도, 외부 함수 내의 로컬 변수 값과 내부 함수(중첩 함수)를 사용할 수 있는 기법이다.
- 클로저를 사용하는 경우
- 클로저는 객체와 유사하다.
- 일반적으로 제공해야할 기능(메소드)가 적은 경우, 클로저를 사용하기도 한다.
- 제공해야할 기능이 많은 경우에는 class를 이용하여 구현한다.
- 자세한 것은 예제 코드를 보도록 하자.
- 아래 코드에서 closure_func가 클로저이다.
- #1에서 outer_func()는 호출이 종료된다.
- #2에서 closure_func()는 inner_func함수를 호출한다.
#1에서 외부 함수 호출이 종료되면서 n값은 사라지나, #2에서 closure_func()에서 inner_func가 호출 되면서 이전의 n값인 4를 사용한다. - 심지어 #3에서 외부 함수를 삭제해도 inner_func()와 n값은 살아있는 것을 결과값을 통해 확인할 수 있다.
def outer_func(n):
def inner_func():
print(n)
return "안녕"
return inner_func
closure_func = outer_func(4) #1 First-class 함수
print(closure_func()) #2 Closure 호출
print("-----")
del outer_func #3
print(closure_func())
"""
결과값:
4
안녕
---
4
안녕
"""
- 예시
def multiply(n):
def power(nums):
return nums ** n
return power
power2 = multiply(2)
power3 = multiply(3)
power4 = multiply(4)
print(power2(2)) # 4
print(power3(2)) # 8
print(power4(2)) # 16
- 연습 문제 : 위 예시의 multipy()를 사용해서 아래와 같은 결과값을 출력해보자.
# 결과값
1의 1승 = 1
1의 2승 = 1
1의 3승 = 1
1의 4승 = 1
1의 5승 = 1
---------
2의 1승 = 2
2의 2승 = 4
2의 3승 = 8
2의 4승 = 16
2의 5승 = 32
---------
3의 1승 = 3
3의 2승 = 9
3의 3승 = 27
3의 4승 = 81
3의 5승 = 243
---------
4의 1승 = 4
4의 2승 = 16
4의 3승 = 64
4의 4승 = 256
4의 5승 = 1024
---------
5의 1승 = 5
5의 2승 = 25
5의 3승 = 125
5의 4승 = 625
5의 5승 = 3125
# 정답 코드
def multiply(n):
def power(nums):
return nums ** n
return power
power_list = []
for i in range(1, 5+1):
power_list.append(multiply(i))
for i in range(1, 5+1):
if i >= 2:
print("---------")
for j in range(0, len(power_list)):
print("{}의 {}승 = {}".format(i, j+1, power_list[j](i)))
'언어 > Python' 카테고리의 다른 글
[Python] 인스턴스 메서드 / 정적 메서드 / 클래스 메서드 (0) | 2020.09.08 |
---|---|
[Python] 데코레이터(decorator) (0) | 2020.09.04 |
[Python] datetime.timedelta 객체 (0) | 2020.08.07 |
[Python] 시간 다루기 헷갈리는 부분 정리 (0) | 2020.07.30 |
[Python] pyinstaller를 통해 변환된 .exe파일 실행 오류 해결 (0) | 2020.06.29 |
Comments