TIL 중첩함수 Nested Function

Kim Chioh·2021년 1월 14일
0
post-thumbnail

Why use nested function?

1.가독성
2.Closure

가독성

반복되는 코드가 있다면 중첩함수로 선언, 가독성을 높일 수 있습니다.

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

사전적 의미는 폐쇄. 가둔다. 외부로부터 무언가를 가둠

바로 중첩 함수가 부모 함수의 변수나 정보를 가두어 사용하는 것을 closure라고 합니다.

정리하자면:

1.중첩 함수가 부모 함수의 변수나 정보를 중첩 함수 내에서 사용한다.

2.부모 함수는 리턴값으로 중첩 함수를 리턴한다.

3.부모 함수에서 리턴 했으므로 부모 함수의 변수는 직접적인 접근이 불가능 하지만 부모 함수가 리턴한 중첩 함수를 통해서 사용될 수 있다.

언제씁니까?

어떠한 정보를 기반으로 연산을 실행하고 싶지만 기반이 되는 정보는 접근을 제한하여 노출이 되거나 수정이 되지 못하게 하고 싶을때 사용합니다.

주로 factory 패턴을 구현할때 사용되는데요, factory는 공장이란 뜻이죠.

즉 뭔가를 생성해내는 패턴입니다. 주로 함수나 오브젝트를 생성해내는데 사용됩니다.텍스트

Factory에서 뭔가를 생성해 내기 위해서는 설정값이 필요할것입니다.

그 설정값을 노출하지 않아서 수정이 불가능하게 하면서 해당 설정값을 기반으로한 연산을 할 수 있는 함수를 만들때 closure를 사용할 수 있습니다.

예를 들어 보겠습니다.

만일 주어진 어떠한 숫자의 수(數) 을 구하는 함수는 다음과 같을 것입니다.

def calculate_power(number, power):
    return number ** power

calculate_power(2, 7)
> 128

자 이제, 주어진 숫자의 승을 구하는게 아니라 특정 숫자의 승을 구하는 함수를 구현한다고 생각해봅시다. 예를 들어, 2의 승을 구하는 함수를 구현한다면 다음과 같습니다.

def calculate_power_of_two(power):
    return 2 ** power

calculate_power_of_two(7)
> 128

calculate_power_of_two(10)
> 1024

하지만 위의 함수는 2의 승밖에 구할 수 없습니다.

만일 특정 숫자의 숭을 구하는 함수가 필요 하지만 2가 아니라 설정되는 수의 승을 구하는 함수는 어떻게 구현할 수 있을까요?

이때 closure를 사용할 수 있습니다.

def generate_power(base_number):
    def nth_power(power):
        return base_number ** power
    return nth_power

calculate_power_of_two = generate_power(2)

calculate_power_of_two(7)
> 128

calculate_power_of_two(10)
> 1024

calculate_power_of_seven = generate_power(7)

calculate_power_of_seven(3)
> 343

calculate_power_of_seven(5)
> 16907

위에서는 베이스넘버가 리턴값에 들어가 출력을 담당하는 변수에 들어갔고, 안에 파워함수가 들어가서 중첩되어 출력됩니다.

Assignment, Decorator

Decorator를 구현해보세요.

Decorator는 앞서 배운 closure를 한단계 더 나아가 사용하는 고급 기능입니다.

Decorator는 closure처럼 중첩함수를 리턴하는 함수 이며 다른 함수에 적용해서, 적용된 함수가 실행되기 전에 무조건 실행됩니다. 즉 특정 함수를 실행하기 전에 강제적으로 다른 함수가 먼저 실행된후 실행되도록 하는 강제성을 제공하는 기능입니다.

when to use?

Decorator로 장식할 수 있는 함수는 중첩 함수(nested function)을 리턴하는 함수만 decorator 함수로 사용될 수 있습니다.

네, 그 이유는 decorator의 기능을 다르게 설명 하면 chain of functions, 즉 여러개의 함수가 연속적으로 호출이 자동으로 되게 해주는거죠.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a5f0eefe-41cd-4dfb-828d-a19b6197f8aa/Untitled.png

그러려면 마지막 함수를 제외한 함수들은 그 다음 함수를 리턴해주어야 파이썬이 함수들을 차례대로 호출 해줄 수 있겠죠? (만일 다음 함수를 리턴하지 않고 다른 값을 리턴해버리면 그 다음 함수로 넘어가지 못하고 그냥 함수 실행이 종료되기 때문이죠) 그렇기 때문에 decorator 함수는 그 다음 함수를 리턴해주어야 합니다.

Assignment

왼쪽 상단의 greeting 함수에 적용될 decorator 함수를 구현하여 greeting 함수에 적용해주세요.

Greeting 함수가 호출 되었을때 decorator 함수에 parametor 값이 greeting 함수 리턴값의 다음에 붙혀져서 리턴되어야 합니다. Decorator 함수의 이름은 welcome_decorator 여야 합니다.

예를 들어, 다음 처럼 정의 하여 welcome_decorator decorator를 적용하여 greeting을 호출하면:

@welcome_decorator
def greeting():
    return "Hello, "
greeting()

>>>결과값은 다음과 같아야 합니다.
"Hello, welcome to WECODE!"

@name_decorator("정우성")
def greeting():
return "Hello, "

greeting()

결과값은 다음과 같아야 합니다.

"Hello, 정우성"
profile
Just do what to do

0개의 댓글