본문 바로가기
파이썬/python 문법 & 이론 실습

함수 호출 스택(call stack), 프레임

by Bentist 2022. 2. 18.

파이썬 함수 호출 방식

파이썬의 함수는 스택(stack) 방식으로 호출된다.

즉, 함수를 호출하면 함수의 실행 컨텍스트가 호출된 순서대로 스택 메모리 공간에 차곡차곡 쌓여가고 함수가 끝나면 위쪽 방향으로 사라진다. 이와 같은 콜 스택 자료구조를 통해 현재 실행 중인 서브 루틴의 실행 컨텍스트를 담고 서브 루틴의 실행이 끝났을 때, 제어를 반환할 지점을 보관한다.

 

실행 컨텍스트

자바 스크립트에서 흔히 Execution context라고 하는 실행 컨텍스트는 파이썬에서는 runtime context라고 부르는데, 이 실행 컨텍스트는 코드를 실행하는데 필요한 환경을 담고 있는 객체이다.

더 쉽게 말하자면 코드 덩어리 같은 것이다. 코드 블록은 대부분의 경우 함수가 된다. 이 코드 블록 안에 변수 및 객체, 실행 가능한 코드가 들어있다. 이 코드가 호출되면 실행 컨텍스트가 생성되고, 실행 컨텍스트는 스택 안에 하나씩 차곡차곡 쌓이고, 제일 마지막에 들어온 실행 컨텍스트가 현재 실행되고 있는 컨텍스트가 된다. 현재 실행되고 있는 컨텍스트 안에서 또다른 함수를 실행되면, 새로운 컨텍스트가 생성되어 스택에 들어가고 그 제어권이 컨텍스트로 이동한다.

출처: 우아한Tech, 하루의 실행 컨텍스트

위 동영상은 자바 스크립트의 실행 컨텍스트 내용인데, 그 역할이 파이썬의 frame object와 일치한다. 자바 스크립트의 실행 컨텍스트는 자신을 호출한 이전 실행 컨텍스트 환경으로 돌아갈 수 있는 outer가 있는데, 파이썬의 frame objectf_back 속성도 같은 역할을 한다. 그래서 현재 실행하고 있는 실행 컨텍스트(2층) 내에서 출력하고자 하는 변수의 정보가 없다면, f_back 사다리를 타고 자신을 호출했던 이전 실행 컨텍스트(1층) 환경으로 내려가 변수를 참조하게 된다.

 

frame object

함수를 실행하기 위해 필요한 정보를 담고 있는 객체로, call stack 구조를 만든다.

frame 객체 속성 중 4가지

frame.f_locals 지역 변수의 상태

frame.f_back 이 프레임의 호출자를 말하며, 자신의 함수 실행이 종료되면 호출한 프레임으로 돌아간다.

frame.f_lasti 함수가 가장 최근에 실행한 바이트 코드의 인덱스

frame.f_code 이 프레임에서 실행되는 코드 객체, 즉 이 프레임의 func() 함수와 같은 코드 객체

frame.f_code == func.__code__

import inspect

frame = None
def func():
    global frame
    x = 10
    y = 20
    print(x+y)
    frame = inspect.currentframe()
    
func()    

func.__code__
>> <code object func at 0x000001F830651F50, file "<ipython-input-7-6326023f0e84>", line 4>

frame.f_code
>> <code object func at 0x000001F830651F50, file "<ipython-input-7-6326023f0e84>", line 4>

 

프레임

프레임은 함수와 함수에 속한 변수 정보가 저장되는 메모리 공간으로, 전역 프레임과 스택 프레임으로 구분된다.

전역 프레임은 스크립트 전체에서 접근 가능한 메모리 공간이고, 스택 프레임은 호출된 함수의 지역 변수가 존재하는 메모리 공간이다.

출처: https://dojang.io/mod/page/view.php?id=2341

y=20까지 코드를 실행하면 전역 프레임에 함수 muladd 변수 xy가 할당된다. (함수 muladd는 객체만 생성)

 

출처: https://dojang.io/mod/page/view.php?id=2341

이제 함수 add를 호출하면 함수 add의 스택 프레임이 생성되고 지역 변수 a, b, c가 할당된다.

 

출처: https://dojang.io/mod/page/view.php?id=2341

add 함수에서 다시 mul 함수를 호출하면 함수 mul의 스택 프레임이 만들어지고 지역 변수가 할당된다.

 

출처: https://dojang.io/mod/page/view.php?id=2341

mul 함수가 끝나면 호출했던 add 함수로 돌아가고 mul의 반환값이 add의 스택 프레임에 저장된다. 함수 실행이 종료되면 스택 프레임도 사라지며, 최초 호출자였던 전역 프레임도 메모리 할당이 해제되고 사라진다.

 

 

 

참고: 

https://thebook.io/006950/ch05/

 

컴퓨터 사이언스 부트캠프 with 파이썬: 5장 함수

 

thebook.io

https://docs.python.org/ko/3/library/inspect.html

 

inspect — 라이브 객체 검사 — Python 3.10.2 문서

inspect — 라이브 객체 검사 소스 코드: Lib/inspect.py inspect 모듈은 모듈, 클래스, 메서드, 함수, 트레이스백, 프레임 객체 및 코드 객체와 같은 라이브 객체에 대한 정보를 얻는 데 도움이 되는 몇 가

docs.python.org

https://dojang.io/mod/page/view.php?id=2341 

 

파이썬 코딩 도장: 29.5 함수의 호출 과정 알아보기

지금까지 함수를 만드는 방법을 알아보았습니다. 이번에는 함수 여러 개를 만든 뒤에 각 함수의 호출 과정을 스택 다이어그램(stack diagram)으로 알아보겠습니다. 스택은 접시 쌓기와 같은데 접시

dojang.io

https://www.youtube.com/watch?v=EWfujNzSUmw

 

댓글