Python 기초

10 . 사용자 정의 함수

imysydesu 2026. 5. 28. 10:34

 

 

 

1 . 사용자 정의 함수

 

 

  • 사용자가 특정 작업을 수행하기 위해 직접 작성한 함수
  • 때때로 우리의 요구사항에 맞게 동작하는 함수를 직접 만들어야 함
  • 함수를 사용하는 이유 : 코드의 재사용

 

 

 

 

 

1 - 1 . 함수의 동작

 

 

  • 함수 객체를 메모리에 생성
  • 그 함수 객체에 함수명 이름을 붙임

-> ex) def hello(): print('안녕하세요') a = hello a()

: 함수 복사가 아니라 같은 함수 객체를 참조하는 객체의 이름을 하나 더 만든 것

:  a()를 찍어도 안녕하세요가 출력됨

 

 

- 기본값

 

def  함수명/변수명 (매개변수1, 매개변수2, ...)

        # 함수 내용

        return  결괏값/반환값

 

 

 

 

 

 

1 - 2 . 함수 객체

 

 

 

함수 객체에 들어가 있는 것

  1.  함수 이름
  2. 매개변수 정보
  3. 실행할 코드 정보
  4. 기본값 정보
  5. 전역 네임스페이스 정보
  6. 클로저 정보 (함수 안에 함수를 만들어놓는 경우 그 환경 밖에서 호출되어도 그 정보를 참조할 수 있게 하는 것)

 

 

 

 

 

 

 

 

1 - 3 . 함수 호출 시 메모리에서 일어나는 일

 

 

 

 

  1. add 이름이 가르키는 함수 객체를 찾음
  2. 함수 실행을 위한 새 공간 생성
  3. 매개변수 a, b에 값 연결
  4. 함수 본문 실행
  5. return 값 반환
  6. 함수 실행 공간 제거

-> 이때 만들어지는 새 공간 : 스택 프레임(stack frame)  /  함수 호출 프레임

 

- 스택 : 사용할 때(함수가 생성되면) 스택에 생성되고 사용하지 않으면(함수가 종료되면) 스택에서 제거됨 

            -> LIFO 형식 (Last in First out)

 

 

 

함수 호출 프레임 

 

  • 함수가 호출될 때마다 생성되는 독립적인 실행 공간
  • 해당 함수의 매개변수, 지역 변수, 반환 주소 그리고 실행 상태를 저장하는 구조
  • 스택 형태로 관리되어 함수가 호출될 때마다 쌓이고 실행이 끝나면 제거됨 -> 함수 간 변수 충돌 없음
  • 같은 함수를 여러 번 호출하더라도 매번 새로운 프레임이 만들어지기 때문에 서로 영향을 주지 않고 독립적으로 동작

 

 

 

 


 

 

 

 

2 . 함수 만들기

 

 

 

 

2 - 1 . 매개변수와 반환 값이 없는 함수

 

 

 

 

 

 

2 - 2 . 매개변수가 있고 반환 값이 없는 함수

 

 

 

 

 

 

 

 

 

2 - 3 . 반환 값이 있는 함수

 

- print()만 있는 것은 반환 값이 있는 게 아니라 단지 출력해 줄 뿐

 

 

 

 

 

 

 

 

FuncA -> B -> C -> B -> A 순서로 실행 

 

 

 

 

 

 

 

2 - 4 . 기본값이 설정된 매개변수

 

 

 

- 기본 매개변수는 함수 생성 시 한 번 만들어짐

 

 

 

 

 

  • 안전하지 않은 방식
  • 리스트 등의 값을 초기화해서 사용하지 말 것 ex) items= [] X

 

- 매개변수 값은 함수가 정의되는 시점에 한 번만 생성됨 -> 힙 메모리에 생성

- 함수 객체와 리스트는 계속 연결되어 있는 상태가 되기 때문에 데이터가 누적됨

 

 

 

  • 안전한 방식

 

- 매개변수에 기본값으로 불변 객체인 None 사용

- if items is None: 코드를 사용해 함수 내부에서 리스트를 새로 생성함

- 내부에서 생성되었기 때문에 외부와 연결되지 않음 -> 이전 호출의 영향을 받지 않아 데이터가 누적되지 않음

 

 

 

 

 

 

 

None

 

 

  • 값이 존재하지 않음을 나타냄 (객체가 없음)
  • 비교 시 == 대신 is 사용 ex) if a is None:
  • 함수에서 return을 명시하지 않으면 자동으로 None이 반환
  • 변수 초기화나 아직 값이 정해지지 않음을 표현할 때 사용
  • None은 False로 평가되지만 0, "", [] 등과는 의미적으로 구분됨
  • 연산 대상이 아니기 때문에 산술 연산 사용 시 오류 발생

 

 

 

 

 

2 - 5 . 가변 매개변수

 

 

 

  • 함수 호출 시 *를 사용하면 시퀀스의 요소를 개별적인 위치 인자로 풀어서 전달할 수 있음

 

 

 

 

 

 

 

 

 

 

2 - 6 . 키워드 매개변수

 

 

  • 일반적으로 기본값이 설정된 매개변수와 함께 사용
  • 함수의 매개변수에 기본값을 설정하면 함수를 호출할 때 해당 매개변수를 생략할 수 있음

 

 

 

 

 

 

 

 

2 - 7 . 여러 개의 반환 값

 

 

 

 

 

 

 

 

 

### 언더스코어는 상황에 따라 변수로 쓰이기도 하지만 상황에 따라 변수 이상의 특수한 의미를 가짐###

 

 

 

 

 

 


 

 

 

 

 

3 . 변수의 범위

 

 

 

- 변수의 범위(scope)는 해당 변수가 프로그램 내에서 참조되고 변경될 수 있는 영역을 의미

 

 

 

 

지역 변수 (로컬 변수)

  • 가장 내부의 범위
  • 함수 내에서 정의된 변수
  • 함수 내에서만 접근 가능
  • 스택 메모리에 생성

 

 

 

전역변수

  • 스크립트 전체에서 사용되는 범위
  • 함수 외부에 정의된 변수
  • 모든 함수에서 접근 가능
  • 함수 내부에서 수정하려면 global 키워드 필요
  • 힙 메모리에 생성

 

 

 

 

 

  • 사용 예시

 

 

- 전역 변수 global_var = 10을 global_var = 20으로 로컬 변수 생성

- 출력 시 지정한 값 20으로 출력됨

- modify_global() print(global_var)는 def 함수 밖이므로 로컬 변수가 아닌 전역 변수가 사용되어 10이 출력됨

 

 

 

 

- global_var 앞에 global을 붙임으로써 새로운 지역 변수를 만들지 않고 전역 변수를 그대로 사용함

  -> 전역 변수로 선언

- global_var를 20으로 수정했기 때문에 함수가 종료되어도 쭉 20으로 출력됨

 

 

 

 

-----> 값을 변경할 수 있는 전역 변수를 함부로 사용하는 것은 좋지 않음 

         - 예상치 못한 부작용 등의 어려움이 있음

 

 

 

 

 

 

클로저 변수

 

  • 내부 함수가 외부 함수의 지역변수를 사용하면 파이썬은 그 값을 바로 삭제하지 않고 클로저 공간에 보관

 

 

 

 

클로저 공간

 

  • 내부 함수가 외부 함수의 변수를 계속 사용할 수 있도록 그 값을 따로 저장해 두는 메모리 영역(객체 구조)
  • 일반적으로 함수가 끝나면 그 안의 지역 변수는 사라지지만 내부 함수가 그 변수를 참조하고 있으면 파이썬은 해당 값을 지우지 않고 함수 객체 안에 _closure_ 형태로 보관
  • 저장되는 값은 보통 cell 객체로 감싸져 유지
  • 내부 함수는 실행될 때 이 클로저 공간을 통해 외부 변수에 접근

 

 

len = 5

print(len([1, 2, 3]))

 

-> 내장 함수 'len'을 덮어썼기 때문에 len을 함수가 아닌 변수로 인식해 오류 발생함

 

 

 

 

 

빌트인 함수 

 

  • 별도의 import 없이 바로 사용할 수 있도록 기본적으로 제공되는 함수 ex) print(), range(), len() 등 ...
  • 자동으로 Built-in 네임스페이스에 등록되어 있기 때문에 어디서든 이름만으로 호출 가능
  • 변수 이름을 찾을 때 적용되는 LEGB 규칙(Local, 지역 변수 -> Enclosing, 함수 안의 함수 -> Global, 전역 변수 -> Built-in, 빌트인 함수)에서 마지막 단계에 해당
  • 같은 이름의 변수를 직접 정의하면 빌트인 함수는 가려질 수 있음 

 

 

 

 

 


 

 

 

 

 

4 . 함수 메모리 제거 

 

  • 참조 카운팅, 가비지 컬렉션의 원칙에 따라 동작
  • 함수를 참조하는 변수나 요소가 없게 되면 해당 함수는 가비지 컬렉터에 의해 메모리에서 제거될 수 있음
  • del 명령어를 사용해 함수에 대한 참조를 명시적으로 제거할 수 있음 -> 이것이 함수가 즉시 메모리에서 제거된다는 것은 보장할 수 없음

 

 

 

 

 

 

 

 


 

 

 

 

 

 

5 . 콜백 함수

 

 

 

  • 다른 함수에 인자로 전달되어 특정 시점이나 조건이 되었을 때 나중에 호출되는 함수
  • 변수처럼 전달할 수 있음 -> 어떤 작업이 끝난 뒤 실행할 동작을 미리 정의, 예약할 수 있음
  • 콜백 함수 : 다른 함수에게 맡겨두었다가(주소를 넘겨두고) 필요할 때 호출되도록 하는 함수
  • 공통 작업은 그대로 두고 세부 동작만 바꾸고 싶을 때 유용

 

 

 

 

 

 

 

- sort()는 원본 리스트 자체가 바뀌고 sorted()는 원본 데이터는 그대로 유지하고 새로운 리스트를 반환함

- 상황에 따라 쓰는 것

 

 

 

 

 

 

 


 

 

 

 

 

 

 

6 . 람다 함수

 

 

 

 

  • 이름 없이 간단한 함수를 한 줄로 정의할 수 있는 익명 함수
  • 주로 짧고 일회성으로 사용되는 연산을 표현할 때 사용
  • 일반 함수(def)에 비해 구조는 제한적이지만 코드가 간결해짐
  • sorted, map, filter같은 함수에서 콜백 함수로 자주 사용

 

 

 

- 기본값

 

lambda 매개변수: 반환할_표현식

 

 

 

 

 

 

 

 

 

 

 

 

  • 콜백함수 예제를 람다 함수로 바꾸기 

 

1. 콜백함수 예제

 

 

 

2. 람다 함수