일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Vue
- docker
- merge
- 중급파이썬
- Class
- wetube
- SAA
- socket io
- 채팅
- lambda
- MongoDB
- git
- EC2
- crud
- SSA
- 튜플
- async
- 카톡
- RDS
- react
- node
- TypeScript
- pandas
- dict
- 파이썬
- Props
- S3
- AWS
- NeXT
- flask
- Today
- Total
초보 개발자
31강 네스티드 함수와 클로저 본문
[함수를 만들어서 반환하는 함수]
데코레이터를 이해하기 위해 네스티드 함수와 클로저를 공부해보자.
함수는 객체이고 함수의 이름은 객체를 참조하는 변수이다.
함수 안에서 정의된 함수를 nested함수라고한다. maker는 위에서 정의한 nested함수를 반환하는 함수이다.
우리가 maker라는 함수를 호출하면서 숫자 2를 전달하고 있다. 그럼 함수는 return 2 * n 를 반환하는 형태로 만들어 질 것이다. 그 다음에는 숫자 3을 전달하고 maker함수 안에서 3 * n을 반환하는 함수를 만들었다.
[클로저 (Closure)]
앞서 보인 예제에서 한가지 짚고 넘어갈 내용이 있다. m은 maker 안에서만 존재하는 변수인데.. maker 밖에서도 m이 유효할까??? 변수 m은 maker함수에서 선언된 변수이다.
때문에 다음과 같은 현상이 벌어진다
'변수 m은 maker 함수를 벗어나면 사라져버린다.'
m * n에서 m이 참조하고 있는 값을 가져다 쓰겠다는 것이지. m이 가지고 있는 숫자로 m과 자리를 바꿔버린다는 뜻은 아니다.
return m * n -> return 2 * n ( X )
return m * n -> return 3 * n ( X )
maker함수안에서는! 말이 되는 이야기이다. 하지만 inner함수를 반환을 하니까!! maker함수를 빠져나가버린다.
그럼 반환한 inner함수에 있는 m은 도대체 뭘 참조를 하고 있는 것인가? 이미 레퍼런스 카운트도 0이 되어버려 사라진 상태이다. 사실 이건 실행할 수 없는 문장이다.
maker밖에서 호출하기에 m이 사라진 상태이지만,
m이 가지고 있는 값을 inner 함수가 만들어 질 때 살짝 어딘가에 저장해놓고 쓴다. 그래서 m을 참조하려고 하는 순간에
그 객체 안에서 뒤져 뒤져서 전에 받았던 m값을 찾아서 계산을 하는 것이다. 이걸 클로저라고 한다.
즉 객체 안에다 어떤 변수의 값을 저장해 놓는 기술이라고 할 수 있다.
물론 어딘가에 저장해 놓을 때도 그이름이 그대로 m은 아니다.
진짜 어딘가에 값이 있는지 확인하고 싶다면 아래와 같은 코드를 작성하며 확인할 수 있다.
즉 위의 예제를 실행 결과를 통해서 maker함수 안에 존재하는 네스티드 함수 inner가 변수 m의 값을 저장해 놓는 위치는 다음과 같다고 판단할 수 있다.
__closure__변수의 인덱스 0의 위치에 저장된 객체의 변수인 cell_contents
이로써 함수 객체 안에 값을 저장해 둔다는 사실을 실제로 확인하였다.
'Python > 윤성우 열혈 파이썬' 카테고리의 다른 글
30강 프로퍼티 (0) | 2022.01.25 |
---|---|
29강 __slots__의 효과 (0) | 2022.01.25 |
28강 정보은닉과 __dict__ (0) | 2022.01.24 |
27강 연산자 오버로딩 (0) | 2022.01.24 |
26강 스페셜 메소드 (0) | 2022.01.18 |