def parent_function():
def child_function():
print("this is a child function")
child_function()
parent_function()
# "this is a child function"
중첩함수 (nested 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!")
print_all_elements([1, 2, 3, 4])
우선적으로 print_all_elements 함수에 리스트를 넣고
호출하게 되면 분기문이 실행하게 된다 .
if len(list_of_things) > 0 :
print_each_element(list_of_things)
else :
print("there is nothing!")
여기부터 타게 되고 리스트가 있다면 if 문을 타게 되고 그게 아니라면
else 문을 타게 된다.
지금은 리스트가 있으니깐
print_each_element(list_of_things) 로 print_each_element 함수가 호출이 되면서 파라미터에 [1,2,3,4] 리스트가 전달이 된다.
def print_each_element(things):
for thing in things:
print(thing)
이 함수가 실행이 된다.
중첩 함수를 사용하는 다른 큰 이유는 closure 이다.
Closure 는 사전적의미는 패쇄이다.
파이썬에서 사용하는 closure 도 어떤 것을 외부로 부터 격리해 사용한다는 느낌이 더 크다.
무엇을 격리해 사용하는것일까 ??
부모함수는 중첩 함수를 리턴해 준다.
그리하면 부모함수의 변수를 외부로부터 직접적인 접근은 격리하면서도 중첩 함수를 통해서 격리된 부모함수의 변수를 사용한 연산은 가능하게 해주는 것이다.
정리하면 ,
접근을 제한하여 노출이 되거나 수정이 되지 못하게 하고 싶을때 사용한다.
def calculate_power(number, power):
return number ** power
calculate_power(2, 7)
# 128
2의 7 승이 return 됩니다.
이것을
주어진 숫자의 승을 구하는게 아니라 특정 숫자의 승을 구하는 함수를 구현한다고 생각해 보자.
def generate_power(base_number):
def nth_power(power):
return base_number ** power
return nth_power
calculate_power_of_two = generate_power(2)
print(calculate_power_of_two(7))
# 128