메모리
- 함수의 정의(코드)는 Heap에 상주
- 함수의 실행(상태)는 Call Stack에 임시 생성되었다가 사라진다.
| 구분 | Heap | Call Stack |
|---|
| 저장 대상 | 함수 정의 객체 (PyCodeObject, PyFunctionObject) | 함수 실행 프레임 객체(PyFrameObject) |
| 생성 시점 | 모듈 로드 및 def 문 해석 시점 | 함수 호출 시점(func()) |
| 소멸 시점 | 프로그램 종료 or 가비지 컬렉션(GC) 시점 | 함수 실행 완료 시(return) 즉시 |
| 특징 | 함수를 여러 번 호출해도 단 1개의 원본 객체를 재사용 | 호출할 때마다 새로운 독립 프레임 생성(재귀 호출 포함) |
- stack : LIFO (Last In First Out)
- queue : FIFO (First In First Out)
단계별 메모리 적재 프로세스
- 정의 단계 (def 문 해석)
- 파이썬 인터프리터가 바이트코드를 읽어 Heap에 불변 데이터 구조체인 PyCodeObject와 이를 감싸는 PyFunctionObject를 올린다.
- 호출 단계 (Function Call)
- 함수가 호출되면 Call Stack에 전용 실행 공간인 PyFrameObject가 올라감.
- 매개변수와 지역변수는 프레임 내부의 f_locals 영역에 실시간으로 매핑됨.
- 종료 단계 (Return)
- 함수가 값을 반환하고 종료되면 Call Stack에서 해당 프레임 객체가 POP 되며, 임시 할당 되었던 지역 변수 공간이 소멸
파이썬 함수의 실행 문맥 : Frame Object
- 파이썬 인터프리터는 함수가 호출될 때마다 해당 함수의 실행 상태를 관리하기 위해 Frame Object(PyFrameObject)라는 메모리 구조체를 생성하여 Call Stack에 쌓는다.
프레임 객체의 구성 요소
| 속성명 | 역할 |
|---|
| f_locals | 현재 함수 내부의 지역 변수 및 매개변수를 저장하는 딕셔너리 |
| f_globals | 현재 함수가 속한 모듈의 전역 변수를 참조하는 딕셔너리 |
| f_builtins | 파이썬 내장 함수 및 예외 객체들(print, len 등)이 속한 스코프 딕셔너리 |
| f_back | 현재 프레임을 호출한 이전 프레임(부모 함수/호출자)을 가르키는 포인터 |
| f_code | 함수 바이트코드 및 상수 목록, 변수명 목록 등을 담은 코드 객체 |
함수
3. 위치 인수(Position Arguments) & 키워드 인수 (Keyword Arguments)
- 위치 인수 : 함수 호출할때 매개변수의 순서에 맞게 인수 입력
- 키워드 인수 : 함수 호출할때 매개변수명=값의 형식으로 인수 입력
def add(num1, num2):
return num1+num2
add(10, 20)
add(num1=10, num2=20)
add(num2=20, num1=10)
add(10, num2=20)
add(20, num1=10)
add(num1=10, 20)
4. 기본값 매개변수 (Default Parameter)
- 매개변수에 값을 할당하지 않아도 기본적으로 가질 수 있는 값 설정
- 기본값이 있는 매개변수는 오른쪽 끝부터 차례대로 정의한다.
def add(num1, num2, name, phone='010-xxxx-xxxx'):
result = f"{num1}, {num2}, {name}, {phone}"
return result
print(add(1, 2, 'Kim'))
5. 가변 인수(*args) & 키워드 가변 인수 (**kwargs)
- *args : 가변적인 위치 인수, 매개변수 갯수 상관없이 지정 가능, 키워드 매개변수로는 사용 불가능
- **kwargs : 가변적인 키워드 인수, 매개변수 갯수 상관없이 지정 가능, key-value 형식으로 사용
def add(num1, num2, num3):
return num1 + num2 + num3
print(add(10, 20, 30))
def add(*nums) :
total = 0
for i in nums:
total += i
return total
print(add(10, 20, 30))
def user(**data):
print(f"{data}")
for key,value in data:
print(f'{key} - {value}')
user(name='Kim', age=20, phone='010-0000-1111')
def print_user_info(name, age, **info):
print('name', name)
print('age' , age)
print(info)
print_user_info('kim', 20, phone='010-0000-0000')
def print_user_info(name, age, *args, **kwargs):
print('name:', name)
print('age:', age)
print(args)
print(kwargs)
print_user_info('kim', 20, '010', '2222','3333', address='Seoul')
return 문의 역할과 복수 데이터 반환
- return : 즉시 함수를 종료하고 최종 결과값을 호출부로 반환한다.
def calc(num1, num2):
return num1 + num2, num1 * num2, num1 - num2, num1 / num2
!
my_string = "i love you"
result = my_string.split(" ")
print(result)
'''
변수명.split() -> 매개변수 없으면 연속 공백을 하나로 처리함 - ['i', 'love', 'you']
변수명.split(' ') -> 정확히 스페이스 1개마다 잘라서 빈 문자열 생성 -['i', '', '', '', 'love', 'you']
'''