Python에서 함수는 코드의 재사용성과 구조를 개선하는 가장 기본적이고 강력한 도구입니다. 이번 포스팅에서는 함수의 정의와 호출, 함수의 종류(Built-in Functions와 User-defined Functions), 매개변수와 반환값, 스코프(Scope), 네임스페이스(Namespace), 람다 함수, 재귀 함수까지 Python 함수의 핵심 개념을 살펴보겠습니다.
0. 함수 : Function
'함수(Function)'는 특정 작업을 수행하도록 설계된 코드의 집합입니다. 함수는 입력(매개변수)을 받아 특정 작업을 수행한 뒤 결과(반환값)를 출력할 수 있습니다. 이를 통해 코드의 중복을 줄이고 가독성을 높이며 유지보수를 용이하게 만듭니다.
Python에서 함수는 크게 Built-in Functions와 User-defined Functions로 나뉩니다.
(1) Built-in Functions
Built-in Functions는 Python에서 기본적으로 제공하는 함수들로, 추가적인 설치나 정의 없이 바로 사용할 수 있습니다. 이들은 대부분 자주 사용되는 기능을 포함하며, Python 코드의 효율성을 높이는 데 중요한 역할을 합니다.
• 데이터 타입 변환: int(), float(), str()
• 수학 연산: abs(), pow(), round()
• 문자열 처리: len(), format()
• 컬렉션 처리: sum(), max(), min(), sorted()
• 기타 유용한 기능: print(), input(), type()
Built-in Functions는 Python의 기본 동작을 이해하고 활용하는 데 중요한 기반을 제공합니다.
(2) User-defined Functions
User-defined Functions는 사용자가 특정 작업을 수행하기 위해 직접 정의한 함수입니다. 함수는 def 키워드를 사용해 정의하며, 입력과 출력을 자유롭게 설계할 수 있습니다. 이러한 사용자 정의 함수는 특정 상황에 맞는 맞춤형 기능을 제공합니다.
1. 함수 정의 및 호출 : Defining and Calling a Function
1.1 함수 정의 (Defining)
함수는 def 키워드를 사용하여 정의하며, 함수 이름, 괄호 안의 매개변수, 함수 본문으로 구성됩니다.
• 함수 이름은 의미를 명확히 나타내야 합니다.
• 괄호 안에 매개변수를 지정해 입력값을 받을 수 있습니다.
• return 키워드를 사용해 값을 반환할 수 있습니다.

예제: 두 수의 합을 계산하는 함수

1.2 함수 호출 (Calling)
정의된 함수는 함수 이름과 괄호 안에 인수를 전달하여 호출합니다.

출력 결과:

2. 매개변수와 인수 : Parameters & Arguments
매개변수는 함수 정의 시 사용되며, 호출 시 인수를 통해 값이 전달됩니다.
매개변수(Parameter)
매개변수는 함수 정의 시 입력값을 받을 변수입니다. 함수 호출 시 입력값(인수)이 매개변수에 전달됩니다. Python에서는 다양한 형태의 매개변수를 지원합니다.
• 위치 매개변수 (Positional Parameter): 함수 호출 시 입력값이 정의된 순서대로 매개변수에 전달됩니다.
• 기본값 매개변수 (Default Parameter): 매개변수에 기본값을 설정하면, 호출 시 해당 인수를 생략할 수 있습니다.
• 키워드 매개변수 (Keyword Parameter): 함수 호출 시 매개변수 이름을 명시적으로 지정해 전달합니다.
• 가변 매개변수 (Variable-length Parameter): 매개변수의 개수가 가변적인 경우 사용됩니다.
- *args: 위치 인수를 여러 개 받을 수 있는 매개변수.
- **kwargs: 키워드 인수를 여러 개 받을 수 있는 매개변수.
인수(Argument)
인수는 함수 호출 시 함수에 실제로 전달되는 값입니다. 매개변수와 인수는 함수 호출 과정에서 짝을 이루며 동작합니다.
• 위치 인수 (Positional Argument): 함수 호출 시 매개변수의 순서에 따라 전달됩니다.
• 키워드 인수 (Keyword Argument): 호출 시 매개변수 이름을 명시적으로 지정하여 전달됩니다.
• 가변 인수 (Variable-length Argument): 인수의 개수가 변동적인 경우 사용할 수 있습니다.
2.1 위치 매개변수 (Positional Parameter)
함수 호출 시 인수는 정의된 매개변수의 순서에 따라 전달됩니다.

출력 결과:

2.2 기본 매개변수 값 (Default Parameter)
매개변수에 기본값을 설정하여 함수 호출 시 해당 인수를 생략할 수 있습니다.

출력 결과:

2.3 키워드 인수 (Keyword Argument)
함수 호출 시 매개변수 이름을 명시하여 인수를 전달할 수 있습니다.

출력 결과:

3. 반환값 : Return value
반환값은 함수가 작업을 수행한 결과를 함수 호출자에게 전달하는 값입니다. 반환값은 return 키워드를 사용해 정의합니다.
반환값의 특징
함수는 하나의 반환값만 가질 수 있지만, 다수의 값을 튜플 형태로 반환할 수 있습니다.
예제: 두 수의 곱과 합을 반환하는 함수

출력 결과:

Tip: 반환값이 없는 함수는 None을 반환합니다.

출력 결과:

4. 스코프와 네임스페이스 : Scope and Namespace
Python에서는 스코프(Scope)와 네임스페이스(Namespace)가 변수와 함수의 접근 및 가시성을 결정합니다.
스코프(Scope)
스코프는 변수가 유효한 코드의 범위를 의미합니다. Python은 LEGB 규칙(Local, Enclosing, Global, Built-in)을 통해 변수를 검색합니다.
• 로컬 스코프(Local Scope): 함수 내부에서 생성된 변수.
• 전역 스코프(Global Scope): 함수 외부에서 선언된 변수.
• 비내부적 로컬 스코프(Enclosing Scope): 중첩 함수의 외부 함수에서 생성된 변수.
• 내장 스코프(Built-in Scope): Python의 기본 제공 함수와 객체.
네임스페이스(Namespace)
네임스페이스는 이름과 객체를 매핑하는 저장 공간으로, 이름 충돌을 방지하고 변수 관리를 체계적으로 합니다.
• Local Namespace: 함수 내부의 변수.
• Global Namespace: 모듈 수준의 변수.
• Built-in Namespace: Python 내장 함수 및 객체.
4.1 지역 변수 (Local Variable)
함수 내에서 정의된 변수는 지역 변수로, 함수 내부에서만 접근 가능합니다.

출력 결과:

4.2 전역 변수 (Global Variable)
함수 외부에서 정의된 변수는 전역 변수로, 함수 내부에서도 접근할 수 있습니다.

출력 결과:

4.3 전역 변수 수정
함수 내부에서 전역 변수를 수정하려면 global 키워드를 사용해야 합니다.

출력 결과:

5. 람다 함수 : Lambda
람다 함수는 익명 함수(Anonymous Function)라고도 하며, lambda 키워드를 사용해 간단한 함수를 한 줄로 정의할 수 있습니다.
단일 표현식을 기반으로 하며, 코드의 간결성을 높이는 데 유용합니다.
5.1 람다 함수 기본 구조

람다 함수는 주로 다른 함수와 함께 사용되며, 간단한 계산이나 데이터 처리를 위해 활용됩니다.
5.2 활용 예제
(1) 기본 람다 함수

(2) map() 함수와 람다

(3) filter() 함수와 람다

(4) sorted() 함수와 람다

6. 재귀 함수 : Recursive Function
재귀 함수는 자기 자신을 호출하는 함수입니다. 이를 통해 복잡한 문제를 간결하게 해결할 수 있지만, 종료 조건을 반드시 설정해야 무한 루프와 스택 오버플로우를 방지할 수 있습니다.
예제: 팩토리얼 계산

출력 결과:

주의: 재귀 호출이 너무 깊어지면 RecursionError가 발생할 수 있습니다.
->
재귀 호출이 너무 깊어진다는 말은, 재귀 함수가 자기 자신을 호출하는 과정이 반복되면서 호출 스택(Call Stack)이 한계치를 초과하게 되는 상황을 의미합니다. 이를 무한 재귀 호출 또는 재귀 깊이 초과라고도 합니다.
재귀 함수는 자기 자신을 호출하기 때문에 함수가 끝나기 전에 새로운 호출이 계속해서 스택에 추가됩니다.
하지만 Python에는 스택의 최대 깊이가 제한되어 있습니다. 기본적으로 이 깊이를 초과하면 RecursionError가 발생합니다.
예제: 종료 조건이 없는 재귀 함수

이 코드는 종료 조건 없이 자기 자신을 계속 호출합니다. 결과적으로 스택이 초과되어 아래와 같은 오류가 발생합니다.
출력 결과:

Python에서는 기본 최대 재귀 깊이가 약 1000번으로 설정되어 있습니다. 이 값은 sys 모듈의 sys.getrecursionlimit() 함수를 사용해 확인할 수 있습니다.

sys.setrecursionlimit()을 사용하면 재귀 깊이를 변경할 수 있지만, 값이 너무 크면 메모리 문제가 발생할 수 있으니 주의해야 합니다.

재귀 깊이 초과를 방지하는 방법에는 종료 조건을 추가하거나, 반복문으로 변환하는 것 입니다.
반복문은 호출 스택을 사용하지 않으므로 메모리 초과 문제를 방지할 수 있습니다.


이번 포스팅에서는 Python 함수의 다양한 측면을 살펴보았습니다. Built-in Functions를 활용하면 기본적인 작업을 효율적으로 수행할 수 있으며, User-defined Functions는 특정 상황에 맞는 맞춤형 기능을 제공합니다. 또한, 스코프와 네임스페이스를 이해하면 코드의 가독성과 안정성을 높일 수 있습니다.
이상으로 포스팅 마치겠습니다.
'Language > Python' 카테고리의 다른 글
| <Python>#6 : Python Strings : 기본 개념부터 문자열 메서드까지 (1) | 2025.01.06 |
|---|---|
| <Python>#5 : Python Loop : for와 while로 반복 제어하기 (7) | 2025.01.04 |
| <Python>#4 : Python List : 리스트 생성부터 활용까지 (6) | 2025.01.04 |
| <Python>#3 : Python Control Flow : 조건과 논리로 흐름 제어하기 (7) | 2025.01.03 |
| <Python>#1 : Python 기본 문법 : Python Syntax와 Variable Types (4) | 2025.01.01 |