Python 중첩함수는 왜 쓰는 것일까?
1. 가독성
2. Closure
에 대해서 알아보자.
함수를 중첩해서 쓰는것이 Nested Function함수이다.
일명 중첩 함수!
def parent_function():
def child_function():
print("this is a child function")
child_function()
parent_function()
위 와 같이 나타낼수 있다.
그럼 중첩 함수는 왜 쓰는 것일까?
함수를 사용하는 이유는 반복되는 코드블럭을 함수로 정의해서 효과적으로 코드를 관리하고 가독성을 높이기 위함이다.
중첩 함수도 사용하는 이유는 동일하다. 함수 안의 코드 중 반복되는 코드가 있다면 중첩 함수로 선언하면 부모 함수의 코드를 효과적으로 관리가 가능하다.
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라고 한다.
그리고 부모함수는 중첩 함수를 리턴해준다.
그리하면 부모 함수의 변수를 외부로부터 직접적인 접근은 격리하면서도 중첩 함수를 통해서 격리된 부모 함수의 변수를 사용한 연산은 가능하게 해주는 것이다.
정리하자면
그렇다면 closure는 언제 사용하는 것일까?
어떠한 정보를 기반으로 연산을 실행하고 싶지만 기반이 되는 정보는 접근을 제한하여 노출이 되거나 수정이 되지 못하게 하고 싶을때 사용한다.
주로 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