728x90
반응형
SMALL
1. 클로저(Closure)
- 함수 안의 함수를 결과로 반환할 때, 그 내부 함수를 클로저라고 함
- 콜백함수, 함수의 순차적 실행, 데코레이터 함수에 사용
설명이 어려우니 코드로 이해해보자!
📍 숫자 n을 매개변수로 받고 2 ~ 9를 곱해주는 함수를 만들어보자.
def mul2(n):
return n * 2
mul2(10)
>>> 20
mul2(5)
>>> 10
def mul5(n):
return n * 5
mul5(10)
>>> 50
mul5(5)
>>> 25
이렇게 함수를 하나씩 꼭 만들어야 할까..?😢 class로 만들어보자!
class를 만들긴 했지만 매번 객체를 생성하여야 한다는 단점이 있다.
class Mul:
def __init__(self, m): # 매개변수 숫자를 입력받음
self.m = m # 개체 생성시 입력되는 매개변수 초기화
def mul(self, n):
return self.m * n
mul2 = Mul(2) # 객체 생성, 생성자 m = 2
print(mul2.mul(10)) # 2 * 10
>>> 20
print(mul2.mul(5))
>>> 10 # 2 * 5
mul5 = Mul(5) # 객체 생성, 생성자 m = 5
print(mul5.mul(10))
>>> 50
print(mul5.mul(5))
>>> 25
스페셜 메소드를 사용하여 객체가 실행되면 자동으로 호출되는 함수를 만들어보자.
class Mul:
def __init__(self, m): # 객체 생성할 때 자동으로 호출
print('생성자 호출!')
self.m = m
def __call__(self, n): # 스페셜 메소드 사용, 객체를 실행할 때 자동으로 호출
print('call 호출!')
return self.m * n
mul2 = Mul(2) # 객체 생성
>>> 생성자 호출!
mul2(10) # 객체를 실행할 때 call 메소드호출
>>> call 호출!
20
mul5 = Mul(5) # 객체 생성
>>> 생성자 호출!
mul5(10) # 객체를 실행할 때 call 메소드 호출
>>> 50
✅ 클로저 사용하기!
def mul(m): # 외부함수
def wrapper(n): # 내부 함수(클로저)
return m * n
return wrapper
mul2 = mul(2) # m = 2인 wrapper 함수가 mul2에 저장
print(mul2(10)) # m = 2, n = 10인 wrapper 함수가 실행
>>> 20
mul5 = mul(5) # m = 5인 wrapper함수가 mul5에 저장
print(mul5(10)) # m = 5, n = 10인 wrapper 함수가 실행
>>> 50
2. 데코레이터(Decorator)
- 함수를 꾸며주는 함수
- 함수를 인수로 받는 클로저
- @(어노테이션)을 이용하여 사용
- 반복되는 작업을 여러 함수에 적용할 경우, 기존 함수를 수정하지 않고 추가 기능을 구현하고 싶은 경우
✅ 매개변수로 숫자 2개를 받아 두 수를 더하고 곱하는는 함수를 만들고 함수가 수행되는 시간을 알아보자.
import time
# 더하기
def func1(a, b):
start = time.time() # 현재 시간을 ms 단위까지 나타냄
print('함수가 시작되었습니다')
result = a + b
end = time.time()
print(f'함수 수행시간: {end - start}') # 함수가 수행될 때부터 출력할 때 까지 소요되는 시간(ms) 계산
return result
result = func1(10,3) # 10 + 3
print(result)
>>> 함수가 시작되었습니다
함수 수행시간: 5.078315734863281e-05
13
# 곱하기
def func2(a, b):
start = time.time()
print('함수가 시작되었습니다')
result = a * b
end = time.time()
print(f'함수 수행시간: {end - start}')
return result
result = func2(10,3) # 10 * 3
print(result)
>>> 함수가 시작되었습니다
함수 수행시간: 0.0038857460021972656
30
✅데코레이터를 만들어 클로저를 이용하여 구현해보자!'
# 데코레이터 만들기
def func1(a, b):
result = a + b
return result
def func2(a, b):
result = a * b
return result
def elapsed(func): # 관례적으로 elapsed 사용
def wrapper(a, b): # 클로저 이용
start = time.time()
print('함수가 시작되었습니다')
result = func(a, b) # 함수에 전달된 a, b를 실행
end = time.time()
print(f'함수 수행시간: {end - start}')
return result
return wrapper
deco1 = elapsed(func1) # 외부함수
result = deco1(10, 3)
print(result)
>>> 함수가 시작되었습니다
함수 수행시간: 0.000986337661743164
13
deco2 = elapsed(func2)
result = deco2(10, 3)
print(result)
>>> 함수가 시작되었습니다
함수 수행시간: 0.0010008811950683594
30
✅ 위 코드를 어노테이션(@)을 이용하여 구현하기
def elapsed(func):
def wrapper(a, b): # 클로저 이용
start = time.time()
print('함수가 시작되었습니다')
result = func(a, b) # 함수에 전달된 a, b를 실행
end = time.time()
print(f'함수 수행시간: {end - start}')
return result
return wrapper
@elapsed
def func1(a, b):
result = a + b
return result
@elapsed
def func2(a, b):
result = a * b
return result
result = func1(10,3) # elapsed함수를 실행하여 담을 변수를 별도 만들지 않음
print(result)
>>> 함수가 시작되었습니다
함수 수행시간: 0.0006263256072998047
13
result = func2(10,3)
print(result)
>>> 함수가 시작되었습니다
함수 수행시간: 0.0008640289306640625
30
728x90
반응형
LIST
'Python > Basic' 카테고리의 다른 글
[파이썬, Python] 주피터 노트북 (Jupyter notebook) 설치하기 & 주피터 노트북 사용하기! (1) | 2023.03.14 |
---|---|
[파이썬, Python] 변수 타입 어노테이션에 대해 알아보자! 🧐 (0) | 2023.03.14 |
[파이썬, Python] 인코딩과 디코딩(Encoding & Decoding) - 유니코드(utf-8, utf-16), 아스키 코드(ascii) (0) | 2023.03.14 |
[파이썬, Python] 파일의 입력과 출력 - open(), close(), with구문, readline(), readlines() (0) | 2023.03.13 |
[파이썬, Python] 예외 처리에 대해 알아보자 🧐 (0) | 2023.03.13 |