•Decorator(데코레이터)
Decorator(데코레이터, 함수 장식자, Function Decorator)란 하위 클래스를 직접 사용하지 않고도 함수나 메소드 또는 클래스의 기능을 사용할 수 있다. 즉 Meta(데이터의 데이터) 기능이 있다는 것이다.
더 와닿을 수 있게 말을 하면 함수 장식자는 또 다른 함수를 감싼 함수라고도 표현할 수 있다.
메인 함수가 호출되면 그 반환값이 장식자에게 전달된다. 이 때 함수 장식자는 포함한 함수로 교체하여 함수를 반환한다.
글로만 표현하면 잘 와닿지 않기 때문에 다음 코드와 함께 보자.
# 예시용 함수 3개
def mark_1(fn):
return lambda: "이것은 " + fn()
def mark_2(fn):
return lambda: "함수를 " + fn()
def mark_3():
return "감싼 것입니다."
# 함수 장식자를 사용하지 않고 표현하는 경우
ex = mark_1(mark_2(mark_3))
print(ex())
# 함수 장식자를 사용하는 경우
@mark_1
@mark_2
def ex2():
return "함수에 감싼 것입니다."
print(ex2())
ex2_2 = ex2()
print(ex2_2) # 실행값을 가져온 경우
ex2_3 = ex2_2
print(ex2_3) # 주소값을 가져와 실행해도 된다.
| 이것은 함수를 감싼 것입니다. 이것은 함수를 함수에 감싼 것입니다. 이것은 함수를 함수에 감싼 것입니다. 이것은 함수를 함수에 감싼 것입니다. |
참고로 위에서 'def 함수명(함수명):' <-- 이런 형태로 사용할 수 있는 것은 파이썬이 일급 함수의 특징을 갖고 있기 때문이다.
2023.01.11 - [파이썬] - 파이썬 - 함수 추가 내용(3)_일급 함수와 축약 함수(lambda)
파이썬 - 함수 추가 내용(3)_일급 함수와 축약 함수(lambda)
•일급 함수 임의의 함수를 다른 변수들처럼 동일하게 사용(다루는)할 수 있는 것을 의미한다. 일급함수로 정의되기 위해서는 조건이 있는데 함수 안에 함수(변수처럼)를 선언할 수 있어야 한다
bluenoa.tistory.com
(예시) 반지름을 입력했을 때 원의 넓이를 반환하는 함수를 만들자.
print('원의 넓이를 구하는 식')
def deco_1(fn): # 반지름 제곱해주기
return lambda: int(fn()) ** 2 # 문자 -> 정수형
def deco_2(fn): # 파이 곱해주기
def print_result():
print(fn() * 3.14)
return print_result
def func(): # 반지름 입력
cir_1 = input('반지름을 입력해주세요 : ') # 입력값은 문자로 들어간다.
return cir_1
# 장식자 없이 표현
func1 = deco_2(deco_1(func))
func1()
# 장식자를 사용하여 표현
@deco_2
@deco_1
def func2():
cir_2 = input('반지름을 입력해주세요 : ')
return cir_2
func2()
| 반지름을 입력해주세요 : 15 706.5 반지름을 입력해주세요 : 15 706.5 |
반지름으로 15를 입력했다. 사용하는 사람에 따라 입력값을 다르게 해주면 될 것 같다.
•재귀 함수(Recursive function)
재귀함수란 자기 스스로를 재참조하는 함수를 뜻한다.
즉 하나의 함수에서 자신을 다시 호출하여 작업을 수행하여 주어진 문제를 해결하는 방법이다.
(위 영상은 재귀함수를 재밌게 풀어낸 영상입니다.)
def TNT(n):
if n == 0:
print('펑!')
else:
print(n, end = ' ')
TNT(n - 1) # 값을 하나 빼서 자기 자신을 호출
a = int(input('카운트다운 입력 : '))
TNT(a)
저는 10을 입력했습니다.
| 카운트다운 입력 : 10 10 9 8 7 6 5 4 3 2 1 펑! |
(예시 - 피보나치 수열)
# 피보나치 수열 구현
li = []
def fibonacci(n):
if n == 0 or n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
for i in range(6):
li.append(fibonacci(i))
print(li)
반복문과 range(범위) 문을 사용했기 때문에 0~5의 자리수로 계산해야 한다.
| [1, 1, 2, 3, 5, 8] |
추가 range를 사용하지 않고 최종 값만 출력하는 경우 코드가 조금 바뀐다.
def fibonacci2(n):
if n == 1 or n == 2:
return 1
else:
return fibonacci2(n-1) + fibonacci2(n-2)
a = fibonacci2(6)
print(a)
| 8 |
(예시 - 팩토리얼)
# 팩토리얼 계산
print()
def facto(n):
if n == 1 :
print(n)
return 1 # 1에서는 그냥 자기 자신을 리턴하고 끝남.
print(n, end = ' ')
return n * facto(n -1) # 자신의 값 * 이전의 값
print('결과 : ', facto(10))
| 10 9 8 7 6 5 4 3 2 1 결과 : 3628800 |
추가 예시
재귀함수를 이용해서 애플 매장에서 아이폰을 구매하는 간단한 코드를 작성해보도록 하자.
global Store_code
Store_Code = {1:'가로수길', 2:'여의도', 3:'명동', 4:'잠실'}
list_arr = [[0 for col in range(5)] for row in range(5)]
# print(list_arr)
# Store, Product, Quantity, Price, Amount
def Amount(price, quan): # 최종 물건 값을 계산하는 함수
final_amount = int(price) * int(quan)
return final_amount
def List_info(store, product, quan, price, amount, count): # 정보를 담는 역할
list_arr[count][0] = Store_Code[store]
list_arr[count][1] = product
list_arr[count][2] = quan
list_arr[count][3] = price
list_arr[count][4] = amount
def list_show(count): # 출력
for p in range(count):
for q in range(5):
print(list_arr[p][q], end = '|')
def fun():
count = 0 # 초기 개수는 0
final_amount = 0 # 초기 금액 0
print('지역정보 : 1:신사동, 2:여의도, 3:명동, 4:잠실')
print('제품정보 : 아이폰14, 아이폰14pro')
store_info, product, quan = input('매장정보, 제품명, 수량을 입력해주세요 : ').split(',') # ','로 입력값을 구분
# print(store_info, product, quan) # 확인용
while True:
if product.strip() == '아이폰14': # split() : 기본값은 none, 띄어쓰기와 엔터를 구분하여 자른다.
product = product.strip()
price = 1250000
elif product.strip() == '아이폰14pro':
price = 1550000
product = product.strip()
else:
print('상품명을 잘못입력했습니다.')
break
store = int(store_info) # 매장 정보를 숫자로 변환
amount = Amount(price, quan) # 제품 가격을 계산
List_info(store, product, quan, price, amount, count)
final_amount += amount
count += 1
list_show(count)
print('\n총 건수 : ' + str(count), '총액 : ' + str(final_amount))
re_quest = input('주문을 계속하시겠습니까? [y/n]')
if re_quest == 'y' or re_quest == 'Y':
fun() # 자기 자신을 또 부른다.
elif re_quest == 'n' or re_quest == 'N':
print('주문이 완료되었습니다.')
break # 종료
fun()
지역번호 : 1, 상품명 : 아이폰14, 수량 : 2
입력한 결과
| 지역정보 : 1:신사동, 2:여의도, 3:명동, 4:잠실 제품정보 : 아이폰14, 아이폰14pro 매장정보, 제품명, 수량을 입력해주세요 : 1, 아이폰14, 2 가로수길|아이폰14| 2|1250000|2500000| 총 건수 : 1 총액 : 2500000 주문을 계속하시겠습니까? [y/n]n 주문이 완료되었습니다. |
'파이썬(Python)' 카테고리의 다른 글
| 파이썬 - 클래스(1) (0) | 2023.01.25 |
|---|---|
| 파이썬 - 읽고 쓰기와 모듈(Module) (2) | 2023.01.19 |
| 파이썬 - 함수 추가 내용(3)_일급 함수와 축약 함수(lambda) (0) | 2023.01.11 |
| 파이썬 - 함수 추가 내용(2) (0) | 2022.12.14 |
| 파이썬 - 함수 추가 내용(1) (1) | 2022.10.25 |