๐Ÿฅ Python 04. nested function

matisseยท2020๋…„ 3์›” 26์ผ
0

Python Basic

๋ชฉ๋ก ๋ณด๊ธฐ
5/6

nested function์„ ๋ฐฐ์šฐ๋ฉด์„œ ์›๋ž˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ •๋ฆฌํ•œ ํฌ์ŠคํŠธ์— ๋ง๋ถ™์ด๋ ค๊ณ  ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด์šฉ์ด ๋„ˆ ๋ฌด ๋„ˆ ๋ฌด ์–ด๋ ค์›Œ์„œ. . . ๋”ฐ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค ๐Ÿคฏ

โœ… nested function

ํ•จ์ˆ˜ ์•ˆ์—์„œ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ค‘์ฒฉํ•จ์ˆ˜(nested function) ํ˜น์€ ๋‚ด๋ถ€ ํ•จ์ˆ˜๋Š” ๋ถ€๋ชจ ํ•จ์ˆ˜ ์•ˆ์—์„œ๋งŒ ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋ถ€๋ชจ ํ•จ์ˆ˜๋ฅผ ๋ฒ—์–ด๋‚˜์„œ ํ˜ธ์ถœ๋  ์ˆ˜ ์—†๋‹ค.

def parent_function():
    def child_function():
        print("this is a child function")

    child_function()

parent_function() # result: "this is a child function"

๐ŸŒˆํŠน์ง•

  • ์ค‘์ฒฉ ํ•จ์ˆ˜๋Š” ๋ถ€๋ชจ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜ ๋“ฑ์„ ์ค‘์ฒฉ ํ•จ์ˆ˜ ๋‚ด์—์„œ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋ถ€๋ชจ ํ•จ์ˆ˜๋Š” ๋ฆฌํ„ด๊ฐ’์œผ๋กœ ์ค‘์ฒฉ ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.
  • ๋ถ€๋ชจ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜๋Š” ์ง์ ‘์ ์ธ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅ ํ•˜์ง€๋งŒ, ๋ถ€๋ชจ ํ•จ์ˆ˜๊ฐ€ ๋ฆฌํ„ดํ•œ ์ค‘์ฒฉ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

1. ์‚ฌ์šฉ ์ด์œ 

- ๊ฐ€๋…์„ฑ

ํ•จ์ˆ˜ ์•ˆ์— ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์ค‘์ฒฉ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•ด ๋ถ€๋ชจ ํ•จ์ˆ˜์˜ ์ฝ”๋“œ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.

def print_all_elements(list_of_things):
    ## ์ค‘์ฒฉํ•จ์ˆ˜ ์„ ์–ธ
    def print_each_element(things): # ๋ฆฌ์ŠคํŠธ ์š”์†Œ๋ฅผ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด์ฃผ๋Š” ํ•จ์ˆ˜
        for thing in things:
            print(thing)

    if len(list_of_things) > 0:
        print_each_element(list_of_things)
    else:
        print("There is nothing!")

- closure

์ค‘์ฒฉ ํ•จ์ˆ˜๊ฐ€ ๋ถ€๋ชจ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜๋‚˜ ์ •๋ณด๋ฅผ ๊ฐ€๋‘์–ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์ค‘์ฒฉ ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€๋ชจ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜์— ๋ฐ”๋กœ ์ ‘๊ทผ์€ ๋ถˆ๊ฐ€ํ•˜๋‚˜, ์ค‘์ฒฉ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์€ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๐ŸŒˆ ์šฉ๋ก€:

  • factory ํŒจํ„ด ๊ตฌํ˜„: factory์˜ ๋œป์€ ๊ณต์žฅ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๋ญ”๊ฐ€๋ฅผ ์ƒ์„ฑํ•ด๋‚ด๋Š” ํŒจํ„ด์ธ๋ฐ, ์ฃผ๋กœ ํ•จ์ˆ˜๋‚˜ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  • ํŠน์ • ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์ง€๋งŒ, ๊ทธ ์ •๋ณด์— ์ ‘๊ทผ์„ ์ œํ•œํ•˜์—ฌ ๋…ธ์ถœ ํ˜น์€ ์ˆ˜์ •์„ ๋ชปํ•˜๊ฒŒ ํ•˜๊ณ  ์‹ถ์„๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
def generate_power(base_number):
    def nth_power(power):
        return base_number ** power 
    	# ๋ถ€๋ชจ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜์ธ base_number๊ฐ€ ์ค‘์ฒฉ ํ•จ์ˆ˜์— ์‚ฌ์šฉ๋จ (closure)
    return nth_power # ์ค‘์ฒฉ ํ•จ์ˆ˜๊ฐ€ ๋ถ€๋ชจ ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ ๊ฐ’์œผ๋กœ ๋ฆฌํ„ด
 
calculate_power_of_two = generate_power(2)
calculate_power_of_two(7) # base_number๊ฐ€ 2๋กœ ์ด๋ฏธ ์…‹ํŒ…๋œ ํ•จ์ˆ˜
> 128

calculate_power_of_seven = generate_power(7)
calculate_power_of_seven(3)
> 343

โœ… decorator

์‚ฌ์‹ค ๋”ฐ๋กœ ์ •๋ฆฌํ•˜๊ฒŒ๋œ๊ฑด stack overflow์— ์ง„์งœ ์ž˜ ์ •๋ฆฌํ•ด์ค€ ์‚ฌ๋žŒ์ด ์žˆ์–ด์„œ ๊ฐ€๋Šฅํ–ˆ๋‹ค. ๋‚ด์šฉ์ด ์—„์ฒญ ๋งŽ๊ณ  ๊ธธ์–ด์„œ ์ฝ์„ ๋•Œ ์•ฝ๊ฐ„์˜ ์ธ๋‚ด์‹ฌ์ด ํ•„์š”ํ•œ๋ฐ, ๋‹จ๊ณ„์ ์œผ๋กœ ์นœ์ ˆํ•˜๊ฒŒ ์„ค๋ช…ํ•ด์ฃผ์–ด์„œ ๋ฒˆ์—ญํ•ด๋†“์œผ๋ ค๊ณ  ํ•œ๋‹ค.

์šฐ์„  ์งˆ๋ฌธ์˜ ์‹œ์ž‘์€ decorator๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜ ๋‚ด์šฉ์„ ํƒœ๊ทธ<b>, <i>๋กœ ๊ฐ์Œ€ ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ๋ฌธ์ œ์˜€๋‹ค.

๋ฌด๋ ค 2,800์—ฌ๋ฒˆ์˜ ์ถ”์ฒœ์„ ๋ฐ›์€ ๋‹ต๊ธ€๋„ ์ข‹๊ณ , ๋‚ด๊ฐ€ ์˜ฎ๊ธฐ๊ณ  ์žˆ๋Š” ๊ฐœ๋…๊นŒ์ง€ ์ •๋ฆฌํ•ด์ค€ ๋‹ต๋ณ€์€ ์ถ”์ฒœ์ด ๊ฑฐ์˜ 4,000์—ฌ๋ฒˆ์ด๋‹ค. ๋‚˜๋„ ๊ฐ๋™๋ฐ›์•„์„œ ์ถ”์ฒœํ–ˆ๋‹ค๐Ÿฅบ

1. ์ •์˜

decorator๋Š” ๊ฐ์‹ธ๋Š” ๊ฒƒ(wrappers)์ด๋‹ค. ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค์ง€ ์•Š๊ณ , decorateํ•˜๊ณ ์ž ํ•˜๋Š” ํ•จ์ˆ˜์˜ ์ „์ด๋‚˜ ํ›„์— ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ค€๋‹ค.

2. Reminder

decorator๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์ „์—, ์šฐ์„  ํŒŒ์ด์ฌ์—์„œ ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด๋ผ๋Š” ์‚ฌ์‹ค์„ ๊ธฐ์–ตํ•ด์•ผ ํ•œ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ๊ฐ์ฒด๋กœ์„œ ๊ธฐ๋Šฅํ•˜๋Š” 4๊ฐ€์ง€ ์‚ฌ๋ก€๋ฅผ ์‚ดํŽด๋ณด์ž.

- functions can be assigned to a variable.

  • ํ•จ์ˆ˜๋Š” ๋ณ€์ˆ˜์— ํ• ๋‹น๋  ์ˆ˜ ์žˆ๋‹ค.
def shout(word="yes"):
    return word.capitalize()+"!"
print(shout()) # output 'Yes!'

scream = shout # ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€์ˆ˜์— assignํ•  ์ˆ˜ ์žˆ๋‹ค. 
print(scream()) # output: 'Yes!'

- functions can be defined in another function.

  • ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜ ์•ˆ์—์„œ ์ •์˜๋  ์ˆ˜ ์žˆ๋‹ค.
def talk():
    def whisper(word="yes"): # ํ•จ์ˆ˜ ๋‚ด์—์„œ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
        return word.lower()+"..."
    print(whisper())

talk() # output: "yes..." whisper๋Š” talk ๋ฐ–์— ์กด์žฌํ•˜์ง€ ์•Š์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ฒฐ๊ณผ๊ฐ’์ด ๋‚˜์˜จ๋‹ค.

- a function can return another function.

  • ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ returnํ•  ์ˆ˜ ์žˆ๋‹ค.
def getTalk(kind="shout"):
    def shout(word="yes"):
        return word.capitalize()+"!"

    def whisper(word="yes") :
        return word.lower()+"...";

    if kind == "shout":
        # ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ด„ํ˜ธ๋Š” ์“ฐ์ง€ ์•Š๋Š”๋‹ค.
        return shout  # ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.
    else:
        return whisper
        
talk = getTalk()      
print(talk) 
#outputs : <function shout at 0xb7ea817c> 
#talk ํ•จ์ˆ˜์˜ ๊ฐ์ฒด ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
print(talk())
#outputs : Yes!
#()๊ด„ํ˜ธ๋ฅผ ๋ถ™์ž„์œผ๋กœ์จ ํ•จ์ˆ˜ ๋‚ด์—์„œ ์ •์˜ํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

- you can pass a function as a parameter

ํ•จ์ˆ˜๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ์จ ๋„˜๊ธธ ์ˆ˜ ์žˆ๋‹ค.

def doSomethingBefore(func): 
    print("I do something before then I call the function you gave me")
    print(func())

doSomethingBefore(scream) #์œ„์—์„œ ์ •์˜ํ–ˆ๋˜ ํ•จ์ˆ˜๋ฅผ assignํ•œ ๋ณ€์ˆ˜
#outputs: 
#I do something before then I call the function you gave me
#Yes!

3. ์ƒ์„ฑ

์ˆ˜๋™์œผ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ํ•จ์ˆ˜ ์ด๋ฆ„์„ ๊ด€๋ จ๋˜๊ฒŒ ๋ถ™์—ฌ์ฃผ๋‹ˆ๊นŒ ๊ธธ์–ด๋„ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ๊ฒƒ ๊ฐ™๋‹ค. ๋‹ต๋ณ€์ž๊ฐ€ ์ฃผ์„์„ ํ†ตํ•ด ๊ณผ์ • ํ•˜๋‚˜ํ•˜๋‚˜ ์„ค๋ช…ํ•ด์ฃผ์–ด์„œ ๊ธธ์–ด์ง€์ง€ ์•Š๋„๋ก ๋ช‡ ๋ฌธ์žฅ๋งŒ ์ง€์šฐ๊ณ  ๋ณ€์—ญํ•˜์˜€๋‹ค.

# decorator๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ์„œ ๋ฐ›๋Š” ํ•จ์ˆ˜์ด๋‹ค.
def my_shiny_new_decorator(a_function_to_decorate):

    # decorator ์•ˆ ์ชฝ ๋“ค์–ด์˜ค๋ฉด ๋ฐ”๋กœ ๊ฐ์‹ธ๋Š” ํ•จ์ˆ˜(wrapper)๋ฅผ ์ •์˜ํ•œ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” original ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ์„œ original ํ•จ์ˆ˜์˜ ์ „ ํ›„์— ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๊ฒƒ์ด๋‹ค.
    def the_wrapper_around_the_original_function():

        # original ํ•จ์ˆ˜ ์ „์— ์‹คํ–‰๋  ์ฝ”๋“œ๋ฅผ ๋„ฃ๋Š”๋‹ค.
        print("Before the function runs")

        # original ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
        a_function_to_decorate()

        # # original ํ•จ์ˆ˜ ํ›„์— ์‹คํ–‰๋  ์ฝ”๋“œ๋ฅผ ๋„ฃ๋Š”๋‹ค.
        print("After the function runs")

    # ์ด ์‹œ์ ์—์„œ, "a_function_to_decorate"๋Š” ์•„์ง๊นŒ์ง€ ์‹คํ–‰๋œ ์ ์ด ์—†๋‹ค. ์ •์˜๋œ ํ•จ์ˆ˜ ๋‚ด์— ์กด์žฌํ•  ๋ฟ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  wrapper ํ•จ์ˆ˜(ํ•จ์ˆ˜์™€ ์ฝ”๋“œ๋“ค์„ ๊ฐ–๊ณ  ์žˆ๋Š”)๋ฅผ returnํ•ด ์‚ฌ์šฉํ•  ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋œ ์ƒํƒœ๋กœ ๋งŒ๋“ ๋‹ค. 
    return the_wrapper_around_the_original_function

# ๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ๋Š” ๋งŒ์ง€๊ณ  ์‹ถ์ง€ ์•Š์€ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค๊ณ  ์ƒ์ƒํ•˜์ž.
def a_stand_alone_function():
    print("I am a stand alone function, don't you dare modify me")

# ํ•ด๋‹น ํ•จ์ˆ˜์˜ ํ–‰๋™ ๋ฒ”์œ„๋ฅผ ํ™•์žฅํ•˜๊ธฐ ์œ„ํ•ด decorate๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ƒฅ decorator์— ํ•จ์ˆ˜๋ฅผ passํ•˜๋ฉด ๋œ๋‹ค.

a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function_decorated()
#outputs:
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs

#์œ„๋Š” decorator๋ฅผ ํ†ต๊ณผํ•œ ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— assignํ•œ ๊ฒƒ์ด๊ณ , ์•„๋ž˜์™€ ๊ฐ™์ด ๋งค๋ฒˆ decorator์™€ ํ•จ๊ป˜ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค. 
a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function()

๊ทธ๋Ÿฌ๋‹ˆ๊นŒ decorator๋Š” ๋‚ด๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ์ค„ ์ˆ˜ ์žˆ๊ณ , ํ•จ์ˆ˜๋ฅผ decorator์— pass๋งŒ ํ•˜๋ฉด ๋‚ด ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ๋ชจ์Šต์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š”๊ฑฐ๋‹ค. ์—„์ฒญ๋‚˜๊ฒŒ ๊ธธ์ง€๋งŒ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค.

4. syntax

decorator syntax๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ํ•จ์ˆ˜์— ์ž์œ ์ž์žฌ๋กœ ๋ถ™์ผ ์ˆ˜๋„ ์žˆ๋‹ค. decorator ์ด๋ฆ„ ์•ž์— @๋ฅผ ๋ถ™์—ฌ์„œ ์“ด๋‹ค.

@my_shiny_new_decorator
def another_stand_alone_function():
    print("Leave me alone")
    
another_stand_alone_function()  
#outputs:  
#Before the function runs
#Leave me alone
#After the function runs

5. ๊ท€์—ฌ์šด ์˜ˆ์‹œ

๋‹ต๋ณ€์ž๊ฐ€ ํŠน์ˆ˜ ๊ธฐํ˜ธ๋กœ ํ–„๋ฒ„๊ฑฐ๋ฅผ ๋งŒ๋“œ๋Š” decorator๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ๋„˜ ๊ท€์—ฝ๊ธฐ๋„ ํ•˜๊ณ  wrapper๋ผ๋Š” ๊ฐœ๋…์„ ๋ณด๋‹ค ์ž˜ ์™€๋‹ฟ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“  ๊ฒƒ ๊ฐ™๋‹ค. (๋˜‘๋˜‘ํ•˜๊ณ  ์„ผ์Šค์žˆ์–ด..)

def bread(func):
    def wrapper():
        print("</''''''\>")
        func()
        print("<\______/>")
    return wrapper

def ingredients(func):
    def wrapper():
        print("#tomatoes#")
        func()
        print("~salad~")
    return wrapper
    
@bread
@ingredients
def sandwich(food="--ham--"):
    print(food)

sandwich()
#outputs:
#</''''''\>
# #tomatoes#
# --ham--
# ~salad~
#<\______/>

6. ๊ณผ์ œ

๊ทธ๋ž˜์„œ ๋‚ด๊ฐ€ ๊ณผ์ œํ•˜๋ฉด์„œ ์ฒ˜์Œ์œผ๋กœ ์ œ์ผ ์–ด๋ ต๋‹ค๊ณ  ๋Š๋‚€ ๋ฌธ์ œ๊ฐ€ ... ์•„๋ž˜ ์กฐ๊ฑด์—์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด "Hello, ์˜ˆ๋‹ˆ"๊ฐ€ ๋‚˜์˜ค๋„๋ก decorator๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

@name_decorator("์˜ˆ๋‹ˆ")
def greeting():
  return "Hello, "
  
greeting()

์™œ ๊ณ„์† ํ—ค๋งธ๋ƒ๋ฉด, ๋ณดํ†ต python decorator๋ฅผ ๊ตฌ๊ธ€๋งํ•  ๊ฒฝ์šฐ decorator์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ original function์ด ๋“ค์–ด๊ฐ„๋‹ค. stack overflow ์นœ์ ˆํ•œ ๋‹ต๋ณ€์ž์˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋‚ด๊ฐ€ decorateํ•˜๊ณ ์ž ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋“ค์–ด๊ฐ€๊ณ , ํ•จ์ˆ˜ ์œ„์•„๋ž˜๋กœ wrapper๊ฐ€(๋Œ€๋ถ€๋ถ„ print๋กœ ์ด๋ค„์ง„ ์ฝ”๋“œ) ๊ฐ์‹ธ๋„๋ก ์˜ˆ์‹œ๋ฅผ ๋“ ๊ฒŒ ๋Œ€๋ถ€๋ถ„์ด๋‹ค.

๊ทผ๋ฐ ๋ฌธ์ œ์—์„œ๋Š” decorator ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋ณ€์ˆ˜์„ ๋ฐ›๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‹ฌ์ง€์–ด ํ•จ์ˆ˜ ์œ„์•„๋ž˜๋กœ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋„ ์•„๋‹ˆ๊ณ  ๊ธฐ์กด ํ•จ์ˆ˜์— ๊ธ€์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋„ ๋ฌธ์ œ๋‹ค. ๊ทธ๋ž˜์„œ ์ฒ˜์Œ์—๋Š” wrapper์— ์ธ์ž๋ฅผ ๋„ฃ์–ด์•ผ๋˜๋Š”์ค„ ์•Œ๊ณ  ์—„์ฒญ ํ—ค๋งธ๋‹ค.

wrapper parameter

๋งŒ์•ฝ wrapper์— parameter๋ฅผ ๋„ฃ๊ฒŒ ๋˜๋ฉด ๋‚ด๊ฐ€ decorator๋กœ ๊ฐ์‹ธ๋Š” ํ•จ์ˆ˜์— ๋ณ€์ˆ˜๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ๊ธฐ๋ถ„์— ๋”ฐ๋ผ ๋ฌด์–ธ๊ฐ€๋ฅผ ์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค.

def my_deco(someone, feeling): # decorator์— ๋„ฃ์„ ๋ณ€์ˆ˜
  def inner_deco(func): # decorator๋กœ ๊ฐ์Œ€ ํ•จ์ˆ˜๋ฅผ ์ •์˜
    def wrapper(sth): # ๊ฐ์‹ธ์ง€๋Š” ํ•จ์ˆ˜์— parameter๋ฅผ ์ถ”๊ฐ€ํ•˜๋„๋ก ๋งŒ๋“ ๋‹ค. 
      func(sth)
      print(f'because {someone} looks {feeling}')
    return wrapper
  return inner_deco

@my_deco('yeeun', 'sad')
def giver(sth): # ๋งŒ์•ฝ wrapper์—์„œ parameter๋ฅผ ๋„ฃ์ง€ ์•Š์œผ๋ฉด error๊ฐ€ ๋œฌ๋‹ค
  print(f'give {sth}')
  
my_deco('flower') 
#result:
#give flower
#because yeeun looks sad

๋‹ค์‹œ ๋Œ์•„์™€์„œ, ์ด๋ฆ„์„ ๋„ฃ์–ด์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๋ฉดname_decorator(name)๊นŒ์ง€๋Š” ๋ถ„๋ช…ํžˆ ๋งž๋Š”๋ฐ, ์˜ˆ์‹œ๋“ค์—์„œ๋Š” ๋‹ค ํ•จ์ˆ˜๋ฅผ ๋„ฃ๊ณ , ๋„๋Œ€์ฒด ์ € name์„ ์–ด๋””์— ๋„ฃ์–ด์•ผํ• ์ง€ ๋ชจ๋ฅด๊ฒ ๋Š”๊ฑฐ๋‹ค... ๐Ÿ˜ญ

์•Œ๊ณ ๋ณด๋‹ˆ ์•ˆ์—์„œ decorator๋ฅผ ๋˜ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ๋˜๊ฑฐ์˜€๋‹ค. ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœํ•ด์•ผ๋˜๋Š”๋ฐ ๋„ฃ์–ด์•ผ ํ•˜๋‹ˆ๊นŒ, ์ค‘์ฒฉ ํ•จ์ˆ˜๋ฅผ ์“ด๊ฑฐ๋‹ค.

๊ทธ๋‹ˆ๊นŒ ๋‘๋ฒˆ ์ค‘์ฒฉ๋œ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ๋˜ ๊ฒƒ์ด๊ณ , ํ•จ์ˆ˜์™€ ์ด๋ฆ„์„ ๋”ํ•  ๋•Œ๋Š” ๊ทธ๋ƒฅ printํ•˜๊ฑฐ๋‚˜ returnํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋‹ด์•˜์–ด์•ผ ํ–ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๊ฐ’์„ ๋‹ด์„์ง€ ๋ชจ๋ฅด๊ฒ ์œผ๋ฉด ๋นˆ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋„ฃ๊ฑฐ๋‚˜ ๋ณ€์ˆ˜๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด ํ•ฉ์น˜๋Š” ๊ฒƒ์ด ํ•ญ์ƒ ๋‹ต์ด ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

def name_decorator(name):
  def decorator(func):
    def wrapper():
      result = func()+name
      return result
    return wrapper
  return decorator
  
@name_decorator("์˜ˆ๋‹ˆ")
def greeting():
  return "Hello, "
  
greeting() #output: "Hello, "์˜ˆ๋‹ˆ"

0๊ฐœ์˜ ๋Œ“๊ธ€