Python

[Python] ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ (Decorator)

jjingle 2024. 1. 31. 17:01

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ (Decorator) ?

- ํ•จ์ˆ˜ ์•ž๋’ค์— ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด์„œ ์† ์‰ฝ๊ฒŒ ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฒ•
- Closure function
- ์—ฌ๋Ÿฌ ํ•จ์ˆ˜์— ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ @๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ•˜๋‚˜๋กœ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ถ”๊ฐ€

 

 

Closure function 

  • ํ•จ์ˆ˜์™€ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ•จ๊ป˜ ๋ณต์‚ฌ, ์ €์žฅํ•ด์„œ ๋ณ„๋„ ํ•จ์ˆ˜๋กœ ํ™œ์šฉํ•˜๋Š” ๊ธฐ๋ฒ•
  • ์™ธ๋ถ€ ํ•จ์ˆ˜๊ฐ€ ์†Œ๋ฉธํ•˜๋”๋ผ๋„, ์™ธ๋ถ€ ํ•จ์ˆ˜ ์•ˆ์— ์žˆ๋Š” ๋กœ์ปฌ ๋ณ€์ˆ˜ ๊ฐ’๊ณผ ์ค‘์ฒฉํ•จ์ˆ˜(๋‚ด๋ถ€ํ•จ์ˆ˜)๋ฅผ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
def outer_func(num):
  #์ค‘์ฒฉ ํ•จ์ˆ˜์—์„œ ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜์— ์ ‘๊ทผ ๊ฐ€๋Šฅ
  def inner_func():
    print(num)
    return 'hi'
    
  return inner_func #์ค‘์ฒฉ(๋‚ด๋ถ€) ํ•จ์ˆ˜ ์ด๋ฆ„์„ ๋ฆฌํ„ด
  
closure_func = outer_func(10) #First-class function
closure_func() #<---Closure ํ˜ธ์ถœ

#10
#'hi'
  • ์˜ˆ์ œ ์ฝ”๋“œ ๋ถ„์„
    • ์œ„์˜ ์˜ˆ์ œ์—์„œ closure_func์ด ๋ฐ”๋กœ closure
    • closure_func = outer_func(10)์—์„œ outer_funcํ•จ์ˆ˜๋Š” ํ˜ธ์ถœ ์ข…๋ฃŒ
    • closure_func()์€ ๊ฒฐ๊ตญ inner_func ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ
    • outer_func(10) ํ˜ธ์ถœ ์ข…๋ฃŒ ์‹œ num ๊ฐ’์€ ์—†์–ด์กŒ์œผ๋‚˜, closure_func()์—์„œ inner_func์ด ํ˜ธ์ถœ๋˜๋ฉด์„œ ์ด์ „์˜ num ๊ฐ’ 10์„ ์‚ฌ์šฉํ•จ
    • del outer_func ===> outer_func ํ•จ์ˆ˜๋ฅผ ์•„์˜ˆ ์‚ญ์ œํ•ด๋„, inner_func()์™€ num์˜ ๊ฐ’ 10์€ ์‚ด์•„์žˆ๋‹ค!

 

 

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ž‘์„ฑ๋ฒ•

#๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ž‘์„ฑ
def test_decorator(func): #func : ํ•จ์ˆ˜ ์•ˆ์— ๋„ฃ์„ ํ•จ์ˆ˜
  def wrapper():  #ํ˜ธ์ถœํ•  ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ๋Š” ํ•จ์ˆ˜
    print('ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ „')  #ํ•จ์ˆ˜ ์•ž์—์„œ ์‹คํ–‰ํ•  ๋‚ด์šฉ
    func() #ํ•จ์ˆ˜
    print('ํ•จ์ˆ˜ ํ˜ธ์ถœ ํ›„') #ํ•จ์ˆ˜ ๋’ค์—์„œ ์‹คํ–‰ํ•  ๋‚ด์šฉ
    
  return wrapper #closure ํ•จ์ˆ˜๋กœ ๋งŒ๋“ ๋‹ค
  

#๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ ์šฉ
@test_decorator
def logger_check():
  print("ok")
  
logger_check()

'''
ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ „
ok
ํ•จ์ˆ˜ ํ˜ธ์ถœ ํ›„
'''

 

  • closure function ์œผ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ’€์–ด๋ณด๊ธฐ
def test_decorator(func):
  def wrapper(): 
    print('ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ „') 
    func() #ํ•จ์ˆ˜
    print('ํ•จ์ˆ˜ ํ˜ธ์ถœ ํ›„') 
    
  return wrapper 
  
def logger_check():
	print('ok')

decorated_func = test_decorator(logger_check) 
decorated_func()

#@decorator ์‚ฌ์šฉ๊ณผ ๋™์ผํ•œ ๊ฒฐ๊ณผ
'''
ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ „
ok
ํ•จ์ˆ˜ ํ˜ธ์ถœ ํ›„
'''

 

  • ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์žˆ๋Š” ํ•จ์ˆ˜์— Decorator ์ ์šฉ
#์œ ํšจ์„ฑ ๊ฒ€์‚ฌ decorator
def type_checker(function):
  def inner_func(digit1, digit2):
    if (type(digit1) != int) or (type(digit2) != int):
      print('only integer support')
      return
    return function(digit1, digit2)
  return inner_func
  
@type_checker
def multiplexer(digit1, digi2):
  return digit1 * digit2
  
muliplexer(1.1, 2) #only integer support

 

  • ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ๊ด€๊ณ„์—†์ด ๋ชจ๋“  ํ•จ์ˆ˜์— ์ ์šฉ ๊ฐ€๋Šฅํ•œ Decorator 
    • ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์–ด๋–ค ํ˜•ํƒœ์ด๋“  ๊ฒฐ๊ตญ (args, **kwargs)๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅ
    • ๋‚ด๋ถ€ํ•จ์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ์— ์ ์šฉ => ์–ด๋–ค ํ•จ์ˆ˜์ด๋“  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ ์šฉ ๊ฐ€๋Šฅ
#๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ž‘์„ฑ
def general_decorator(function):
  def wraaper(*args, **kwargs):
    print('function is decorated')
    return function(*args, **kwargs)
  return wrapper

#๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ ์šฉ
@general_decorator
def calc_square(digit):
  return digit * digit
  
@general_decorator
def calc_plus(digit1, digit2):
  return digit1 + digit2
  
@general_decorator
def calc_quad(digit1, digit2, digit3, digit4):
  return digit1 * digit2 * digit3 * digit4

 

  • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์—ฌ๋Ÿฌ ๊ฐœ ์ง€์ •
def decorator1(function)
  def wrapper():
    print('decorator1')
    funciton()
  return wrapper
  
def decorator2(function):
  def wrapper():
    print('decorator2')
    funciton()
  return wrapper
  

 #๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋‚˜์—ด ์ˆœ์œผ๋กœ ์‹คํ–‰ ๋จ
@decorator1
@decorator2
def hello():
  print('hello')
  
"""
decorator1
decorator2
hello
"""

 

 

#์ฐธ๊ณ 

https://www.fun-coding.org/post/PL&OOP4-4.html#gsc.tab=0

'Python' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Python] python comprehension  (0) 2024.01.31