티스토리 뷰
중첩함수
중첩 함수(Nested Function)란 함수 내에 위치한 또 다른 함수로, 바깥에 위치한 함수들과 달리 부모 함수의 변수를 자유롭게 읽을 수 있다는 장점이 있다. 중첩 함수가 부모 함수의 변수를 공유하는 예제는 다음과 같다.
def outer_function(t: str):
test: str = t
def inner_function():
print(text)
inner_function(
outer_function("Hello!')
-----
Hello!
여기서 outer_function()은 inner_functuion()을 호출했고, 아무런 파라미터도 남기지 않았지만 부모 함수의 text 변수를 자유롭게 읽어들여 그 값인 Hello!를 출력했다. 이처럼 매번 파라미터를 전달하지 않아도 되기 때문에 구현이 깔끔해진다는 장점이 있다. 아울러 가변 객체인 경우 append(), pop()등 여러 가지 연산으로 조작도 가능하다. 그러나 재할당(=)이 일어날 경우 참조 ID가 변경되어 별도의 로컬 변수로 선언되므로 이 부분은 주의가 필요하다.
연산자 조작
중첩 함수에서 부모 함수에서 선언한 변수를 연산자로 조작하는 경우를 살펴보자.
def outer_function(a: List[int]):
b: List[int] = a
print(id(b), b)
def inner_function1():
b.append(4)
print(id(b), b)
def inner_function2():
print(id(b), b)
inner_function1();
inner_function2();
outer_function([1,2,3])
-----------------------
4598336160 [1, 2, 3]
4598336160 [1, 2, 3, 4]
4598336160 [1, 2, 3, 4]
리스트는 가변 객체이며, 이처럼 중첩 함수내에서 b.append(4)와 같은 형태로 append() 메소드를 사용해 변수를 조작할 수 있다. 이렇게 조작된 값은 부모 함수에서도 그대로 동일하게 적용된다.
재할당
이번에는 재할당으로 참조 ID가 변경되는 경우를 살펴보자
def outer_function(t: str):
text: str = t
print(id(text), text)
def inner_function1():
text = 'World!'
print(id(text), text)
def inner_function2()
print(id(text), text)
inner_function1()
inner_function2()
outer_function('Hello!')
------------------------
4599124144 Hello!
4599124144 World!
4599124144 Hello!
여기서는 불변 객체인 문자형을 예로 들었다. 문자열은 불변 객체이기 때문에 조작할 수 없다. 값을 변경하려면 text = 'World!'와 같은 형태로 새롭게 재할당할 수밖에 없다. = 연산자로 변수를 새롭게 할당하는 경우, ID 값이 변경됨을 확인할 수 있다. 즉 참조 ID가 변경되어 서로 다른 변수가 된다. 중첩 함수인 경우에는 함수 내에서만 사용 가능한 새로운 로컬 변수로 선언되며, 여기서 수정된 값, 즉 재할당된 값은 부모 함수에서는 반영되지 않으므로 주의가 필요하다.
출처
파이썬 알고리즘 인터뷰 (글 : 박상길 그림 : 정진호) [책만]