09_파이썬 함수와 모듈 마스터하기: 기본부터 심화까지 완벽 가이드!
안녕하세요! 오늘은 파이썬 프로그래밍의 핵심 요소인 함수와 모듈에 대해 상세히 알아보겠습니다. 초보자도 쉽게 따라할 수 있도록 실제 예제와 함께 설명드릴게요!
🎯 이 장에서 만들 프로그램 미리보기 {#preview}
이번 포스팅을 통해 다음과 같은 프로그램을 만들어볼 수 있습니다:
- 🎲 로또 번호 추첨기: 함수와 random 모듈을 활용한 번호 생성
- 🐢 거북이 글자쓰기: turtle 모듈을 사용한 그래픽 프로그램
- 📊 성적 관리 시스템: 함수와 모듈을 조합한 실용적 프로그램
🔧 함수의 기본 개념과 구조 {#function-basics}
함수란 무엇인가?
함수는 매개변수를 입력받은 후 그 매개변수를 가공 및 처리해서 반환값을 돌려주는 코드의 집합입니다. 마치 커피머신처럼 원두와 물을 넣으면 커피가 나오는 것과 같죠!
함수의 기본 구조
def 함수이름(매개변수):
"""함수 설명 (독스트링)"""
실행할 코드
return 반환값
중요한 특징
- def로 되어있는 함수 선언 부분은 바로 실행되지 않습니다
- 함수를 호출해야만 실행됩니다
# 함수 정의 (아직 실행되지 않음)
def greet(name):
return f"안녕하세요, {name}님!"
# 함수 호출 (이때 실행됨)
message = greet("파이썬")
print(message) # 안녕하세요, 파이썬님!
함수 vs 메서드
- 함수: 독립적으로 존재하는 코드 블록
- 메서드: 클래스 내부에 속한 함수
# 함수
def my_function():
pass
# 메서드
class MyClass:
def my_method(self): # 클래스 내부의 함수 = 메서드
pass
🌍 변수의 유효 범위: 지역변수 vs 전역변수 {#variable-scope}
변수는 사용할 수 있는 범위에 따라 크게 지역변수와 전역변수로 나눕니다.
지역변수 (Local Variable)
한정된 지역에서만 사용되는 변수로, 함수 내부에서 선언된 변수입니다.
def local_example():
local_var = "지역변수" # 함수 내부에서만 사용 가능
print(local_var)
local_example() # 지역변수
# print(local_var) # 오류! 함수 밖에서는 접근 불가
전역변수 (Global Variable)
프로그램 전체에서 사용되는 변수로, 함수 밖에서 선언됩니다.
global_var = "전역변수" # 프로그램 전체에서 사용 가능
def global_example():
print(global_var) # 전역변수에 접근 가능
global_example() # 전역변수
print(global_var) # 전역변수
global 예약어 사용법
global이라는 예약어로 전역변수라는 것을 명시할 수 있습니다.
count = 0 # 전역변수
def increment():
global count # 전역변수 사용 선언
count += 1 # 전역변수 수정
increment()
print(count) # 1
increment()
print(count) # 2
이름이 같은 경우의 우선순위
x = "전역"
def test():
x = "지역" # 같은 이름의 지역변수
print(x) # 지역변수가 우선
test() # 지역
print(x) # 전역
🔄 함수의 반환값 완전 정복 {#return-values}
함수의 반환값에는 반환값이 있는 함수, 반환값이 없는 함수, 반환값이 여러개인 함수가 있습니다.
1. 반환값이 있는 함수
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8
2. 반환값이 없는 함수
def print_greeting(name):
print(f"안녕하세요, {name}님!")
# return 문이 없음
print_greeting("홍길동") # 안녕하세요, 홍길동님!
3. 반환값이 여러개인 함수
def calculate(a, b):
return a + b, a - b, a * b, a / b
add_result, sub_result, mul_result, div_result = calculate(10, 2)
print(f"덧셈: {add_result}, 뺄셈: {sub_result}") # 덧셈: 12, 뺄셈: 8
print(f"곱셈: {mul_result}, 나눗셈: {div_result}") # 곱셈: 20, 나눗셈: 5.0
pass 예약어 활용
함수를 구현할 때 이름만 만들어 놓고 내용은 pass 예약어를 사용해 비울 수도 있습니다.
def future_function():
pass # 나중에 구현할 예정
def another_function():
pass # 아직 구현하지 않음
📥 매개변수 전달 방식의 모든 것 {#parameters}
함수의 매개변수 전달에는 여러 가지 방법이 있습니다.
1. 기본 매개변수
def introduce(name, age):
print(f"이름: {name}, 나이: {age}")
introduce("김철수", 25) # 이름: 김철수, 나이: 25
2. 기본값을 가진 매개변수
매개변수에 기본값을 설정해 놓고 전달하는 방법
def introduce_with_default(name, age=20):
print(f"이름: {name}, 나이: {age}")
introduce_with_default("이영희") # 이름: 이영희, 나이: 20
introduce_with_default("박민수", 30) # 이름: 박민수, 나이: 30
3. 가변 매개변수 (*args)
매개변수의 개수에 상관없이 모두 처리하고 싶다면 파이썬은 가변 매개변수 방식을 지원합니다. 함수의 매개변수명 앞에 *를 붙이면 됩니다.
def sum_all(*numbers):
total = 0
for num in numbers:
total += num
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5)) # 15
4. 키워드 가변 매개변수 (**kwargs)
함수의 매개변수 앞에 **를 붙이면 튜플이 아닌 딕셔너리 형식으로 전달받습니다.
def print_info(**info):
for key, value in info.items():
print(f"{key}: {value}")
print_info(name="홍길동", age=25, city="서울")
# name: 홍길동
# age: 25
# city: 서울
5. 값에 의한 전달 vs 참조에 의한 전달
파이썬에서 함수의 매개변수 전달은 값에 의한 전달과 참조에 의한 전달 두 가지가 있습니다.
# 값에 의한 전달 (불변 객체)
def change_number(x):
x = 100
num = 10
change_number(num)
print(num) # 10 (변경되지 않음)
# 참조에 의한 전달 (가변 객체)
def change_list(lst):
lst.append(4)
my_list = [1, 2, 3]
change_list(my_list)
print(my_list) # [1, 2, 3, 4] (변경됨)
📦 모듈 활용하기 {#modules}
모듈이란?
모듈은 한마디로 함수의 집합입니다. 함수, 변수, 클래스 등을 모아 놓은 파이썬 파일(.py)을 말합니다.
모듈의 종류
모듈의 종류는 표준모듈, 사용자정의모듈, 서드파티 모듈로 나눌 수 있습니다.
1. 표준 모듈 (Built-in Modules)
import math
import random
import datetime
print(math.pi) # 3.141592653589793
print(random.randint(1, 10)) # 1~10 사이의 랜덤 숫자
print(datetime.datetime.now()) # 현재 시간
2. 사용자 정의 모듈
# my_module.py 파일 생성
def my_function():
return "사용자 정의 함수"
PI = 3.14159
# 메인 파일에서 사용
import my_module
print(my_module.my_function()) # 사용자 정의 함수
print(my_module.PI) # 3.14159
3. 서드파티 모듈
# pip install numpy로 설치 후
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr.mean()) # 3.0
모듈 import 방법
# 전체 모듈 import
import math
print(math.sqrt(16)) # 4.0
# 특정 함수만 import
from math import sqrt, pi
print(sqrt(16)) # 4.0
print(pi) # 3.141592653589793
# 별칭 사용
import math as m
print(m.sqrt(16)) # 4.0
# 모든 함수 import (권장하지 않음)
from math import *
모듈 정보 확인
모듈별로 제공되는 함수는 dir()로도 확인할 수 있습니다.
import math
print(dir(math)) # math 모듈의 모든 함수와 변수 목록
# 특정 함수의 도움말
help(math.sqrt)
언더바(_) 규칙
이름에 언더바(_)가 붙은 것은 언더바를 떼고 임포트해도 됩니다.
# __name__ 같은 특수 변수들
if __name__ == "__main__":
print("이 파일이 직접 실행됨")
📁 패키지 (Package)
패키지는 모듈을 주제별로 분리할 때 주로 사용합니다.
패키지 구조 예시
my_package/
__init__.py
math_module.py
string_module.py
utils/
__init__.py
helper.py
패키지 사용법
# 패키지 import
import my_package.math_module
from my_package.utils import helper
# 패키지 내 모듈 사용
my_package.math_module.add(1, 2)
helper.some_function()
init.py 파일
파이썬 3.3이전에는 패키지 디렉터리에 __init__.py가 필수였으나 3.3이후부터는 이 파일이 없어도 됩니다.
🚀 심화 개념들 {#advanced}
1. 내부함수 (Inner Function)
내부함수는 함수 안에 함수가 있는 형태입니다.
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
add_10 = outer_function(10)
print(add_10(5)) # 15
2. 람다함수 (Lambda Function)
람다함수는 함수를 한 줄로 간단하게 만들어줍니다.
# 일반 함수
def add(x, y):
return x + y
# 람다 함수
add_lambda = lambda x, y: x + y
print(add_lambda(3, 5)) # 8
# 람다 함수 활용 예시
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # [1, 4, 9, 16, 25]
3. map() 함수와 람다
람다함수는 단독으로도 사용되지만, map() 함수와 함께 더 많이 사용됩니다. map() 함수는 리스트에 함수 수식을 모두 한꺼번에 적용시킵니다.
numbers = [1, 2, 3, 4, 5]
# 모든 숫자를 제곱
squared = list(map(lambda x: x**2, numbers))
print(squared) # [1, 4, 9, 16, 25]
# 모든 숫자에 10을 더함
added = list(map(lambda x: x + 10, numbers))
print(added) # [11, 12, 13, 14, 15]
4. filter() 함수
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 짝수만 필터링
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # [2, 4, 6, 8, 10]
5. 재귀함수 (Recursion Function)
재귀함수는 자신이 자신을 호출합니다.
# 팩토리얼
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5)) # 120
# 피보나치 수열
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 55
6. 제너레이터 (Generator)와 yield
함수를 종결하지 않으면서 값을 계속 반환하고 싶다면, yield문을 사용합니다. 함수 안에 yield가 포함된 함수를 제너레이터(생성자) 함수라고 합니다.
def count_up_to(max_count):
count = 1
while count <= max_count:
yield count
count += 1
# 제너레이터 사용
counter = count_up_to(5)
for num in counter:
print(num) # 1, 2, 3, 4, 5
# 무한 시퀀스 생성
def infinite_sequence():
num = 0
while True:
yield num
num += 1
# 메모리 효율적인 사용
gen = infinite_sequence()
for i in range(5):
print(next(gen)) # 0, 1, 2, 3, 4
💡 실전 예제 코드 {#examples}
1. 로또 번호 추첨기
import random
def generate_lotto_numbers():
"""로또 번호 6개를 생성하는 함수"""
numbers = []
while len(numbers) < 6:
num = random.randint(1, 45)
if num not in numbers:
numbers.append(num)
return sorted(numbers)
def print_lotto_numbers(numbers):
"""로또 번호를 예쁘게 출력하는 함수"""
print("🎲 이번 주 로또 번호")
print("-" * 20)
for i, num in enumerate(numbers, 1):
print(f"{i}번째: {num:2d}")
print("-" * 20)
# 실행
if __name__ == "__main__":
lotto_nums = generate_lotto_numbers()
print_lotto_numbers(lotto_nums)
2. 성적 관리 시스템
# grades_module.py
def calculate_average(*scores):
"""여러 과목 점수의 평균을 계산"""
if not scores:
return 0
return sum(scores) / len(scores)
def get_grade(average):
"""평균 점수를 바탕으로 등급 반환"""
if average >= 90:
return 'A'
elif average >= 80:
return 'B'
elif average >= 70:
return 'C'
elif average >= 60:
return 'D'
else:
return 'F'
def print_report(name, **subjects):
"""성적표 출력"""
print(f"\n📊 {name}님의 성적표")
print("=" * 30)
scores = []
for subject, score in subjects.items():
print(f"{subject}: {score}점")
scores.append(score)
avg = calculate_average(*scores)
grade = get_grade(avg)
print("-" * 30)
print(f"평균: {avg:.1f}점")
print(f"등급: {grade}")
print("=" * 30)
# 메인 프로그램
if __name__ == "__main__":
print_report("김학생",
수학=85,
영어=92,
국어=78,
과학=88)
3. 간단한 계산기 모듈
# calculator.py
def add(*args):
"""덧셈"""
return sum(args)
def subtract(a, b):
"""뺄셈"""
return a - b
def multiply(*args):
"""곱셈"""
result = 1
for num in args:
result *= num
return result
def divide(a, b):
"""나눗셈"""
if b == 0:
return "0으로 나눌 수 없습니다"
return a / b
def power(base, exponent=2):
"""거듭제곱 (기본값: 제곱)"""
return base ** exponent
# 계산기 사용 예시
if __name__ == "__main__":
print("🧮 계산기 모듈 테스트")
print(f"덧셈 (1+2+3+4+5): {add(1, 2, 3, 4, 5)}")
print(f"뺄셈 (10-3): {subtract(10, 3)}")
print(f"곱셈 (2*3*4): {multiply(2, 3, 4)}")
print(f"나눗셈 (15/3): {divide(15, 3)}")
print(f"거듭제곱 (2^3): {power(2, 3)}")
print(f"제곱 (5^2): {power(5)}")
🎯 핵심 정리
- 함수는 코드의 재사용성과 가독성을 높이는 핵심 도구
- 지역변수와 전역변수를 구분해서 사용하기
- 매개변수 전달 방식을 상황에 맞게 선택하기
- 모듈을 활용해 코드를 체계적으로 관리하기
- 람다, 제너레이터 등 고급 기능으로 더 효율적인 코드 작성하기
💬 마무리
함수와 모듈은 파이썬 프로그래밍의 핵심입니다. 작은 기능부터 시작해서 점점 복잡한 프로그램을 만들어보세요. 실습을 통해 익히면 금방 실력이 늘 거예요!
궁금한 점이 있으시면 댓글로 남겨주세요. 함께 공부해요! 🚀
🎯 파이썬 함수와 모듈 시험 대비 핵심 요약
📋 시험 출제 포인트 체크리스트
✅ 반드시 암기해야 할 개념들
- [ ] 함수 정의 구조 (def 키워드)
- [ ] 지역변수 vs 전역변수 차이점
- [ ] global 키워드 사용법
- [ ] 매개변수 전달 방식 (*args, **kwargs)
- [ ] return문의 역할과 종류
- [ ] 모듈 import 방법들
- [ ] 람다함수 문법
- [ ] 재귀함수 개념
- [ ] yield와 제너레이터
🔥 1. 함수 기본 개념 (시험 단골 문제)
함수 정의와 호출
# 기본 구조 (암기 필수!)
def 함수이름(매개변수):
실행할 코드
return 반환값
# 중요: def로 정의만 하면 실행되지 않음!
# 반드시 함수를 호출해야 실행됨
🚨 시험 출제 포인트
- 함수 정의 시점 vs 실행 시점 구분
- 함수와 메서드의 차이점
- 독스트링(docstring) 작성법
🌍 2. 변수 유효범위 (필수 암기!)
구분 | 지역변수 (Local) | 전역변수 (Global) |
정의 위치 | 함수 내부 | 함수 외부 |
사용 범위 | 함수 내부만 | 프로그램 전체 |
매개변수 | 지역변수에 포함 | - |
우선순위 | 같은 이름 시 지역변수 우선 | - |
수정 방법 | 직접 수정 가능 | global 키워드 필요 |
global 키워드 사용법 (시험 단골!)
x = 10 # 전역변수
def change_global():
global x # 전역변수 사용 선언
x = 20 # 전역변수 수정
def change_local():
x = 30 # 새로운 지역변수 생성 (전역변수 영향 없음)
🔄 3. 반환값 종류 (분류 문제 단골)
종류 | 특징 | 예시 |
반환값 있음 | return 사용 | def add(a,b): return a+b |
반환값 없음 | return 없음 또는 return만 | def print_hello(): print("안녕") |
반환값 여러개 | 튜플로 반환 | def calc(a,b): return a+b, a-b |
🚨 시험 주의사항
- 반환값이 없는 함수는 None 반환
- 여러 반환값은 튜플로 패킹되어 반환
- return 이후 코드는 실행되지 않음
📥 4. 매개변수 전달 방식 (시험 핵심!)
매개변수 종류별 정리
방식 | 문법 | 설명 | 예시 |
일반 매개변수 | def func(a, b) | 순서대로 전달 | func(1, 2) |
기본값 매개변수 | def func(a, b=10) | 생략 시 기본값 사용 | func(1) |
가변 매개변수 | def func(*args) | 튜플로 여러 값 받음 | func(1, 2, 3) |
키워드 가변 매개변수 | def func(**kwargs) | 딕셔너리로 받음 | func(a=1, b=2) |
🔥 시험 필수 예제
def example_func(a, b=10, *args, **kwargs):
print(f"a: {a}") # 필수 매개변수
print(f"b: {b}") # 기본값 매개변수
print(f"args: {args}") # 가변 매개변수 (튜플)
print(f"kwargs: {kwargs}") # 키워드 가변 매개변수 (딕셔너리)
# 호출 예시
example_func(1, 20, 3, 4, 5, name="김철수", age=25)
📦 5. 모듈 관련 (분류와 import 방법)
모듈 종류
종류 | 설명 | 예시 |
표준 모듈 | 파이썬 기본 제공 | math, random, datetime |
사용자 정의 모듈 | 직접 작성한 .py 파일 | my_module.py |
서드파티 모듈 | 외부에서 제공 | numpy, pandas |
import 방법 (시험 단골!)
# 1. 전체 모듈 import
import math
math.sqrt(16)
# 2. 특정 함수만 import
from math import sqrt, pi
sqrt(16)
# 3. 별칭 사용
import math as m
m.sqrt(16)
# 4. 모든 함수 import (권장하지 않음)
from math import *
🚀 6. 고급 개념 (서술형 단골)
람다함수 (한 줄 함수)
# 일반 함수 → 람다함수 변환
def add(x, y): return x + y
add_lambda = lambda x, y: x + y
# map()과 함께 사용 (시험 단골!)
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers)) # [1, 4, 9, 16, 25]
재귀함수 (자기 자신 호출)
# 팩토리얼 (시험 단골 예제!)
def factorial(n):
if n <= 1: # 종료 조건 (필수!)
return 1
return n * factorial(n-1) # 자기 자신 호출
제너레이터와 yield
def count_generator(n):
i = 0
while i < n:
yield i # 함수를 종료하지 않고 값 반환
i += 1
# 사용법
gen = count_generator(3)
for num in gen:
print(num) # 0, 1, 2
📊 7. 주요 함수와 메서드 총정리
내장 함수 (Built-in Functions)
함수 | 기능 | 예시 |
len() | 길이 반환 | len([1,2,3]) → 3 |
sum() | 합계 계산 | sum([1,2,3]) → 6 |
max() | 최댓값 | max([1,2,3]) → 3 |
min() | 최솟값 | min([1,2,3]) → 1 |
abs() | 절댓값 | abs(-5) → 5 |
round() | 반올림 | round(3.14, 1) → 3.1 |
type() | 타입 확인 | type(123) → <class 'int'> |
dir() | 속성 목록 | dir(math) |
help() | 도움말 | help(print) |
map() | 함수를 시퀀스에 적용 | map(함수, 리스트) |
filter() | 조건에 맞는 요소 필터링 | filter(함수, 리스트) |
zip() | 여러 시퀀스 묶기 | zip([1,2], ['a','b']) |
enumerate() | 인덱스와 값 반환 | enumerate(['a','b']) |
range() | 숫자 범위 생성 | range(0, 10, 2) |
자주 사용하는 모듈별 함수
모듈 | 함수/상수 | 기능 | 예시 |
math | sqrt() | 제곱근 | math.sqrt(16) → 4.0 |
pi | 원주율 상수 | math.pi → 3.14159... | |
ceil() | 올림 | math.ceil(3.1) → 4 | |
floor() | 내림 | math.floor(3.9) → 3 | |
pow() | 거듭제곱 | math.pow(2, 3) → 8.0 | |
random | randint() | 정수 난수 | random.randint(1, 10) |
random() | 0~1 실수 난수 | random.random() | |
choice() | 리스트에서 랜덤 선택 | random.choice([1,2,3]) | |
shuffle() | 리스트 섞기 | random.shuffle(리스트) | |
datetime | now() | 현재 시간 | datetime.datetime.now() |
date() | 날짜 생성 | datetime.date(2023, 12, 25) |
🎯 8. 시험 출제 예상 문제 유형
A. 객관식 (개념 이해)
- 다음 중 전역변수를 함수 내에서 수정할 때 사용하는 키워드는?
- *args와 **kwargs의 차이점은?
- 재귀함수에서 반드시 필요한 것은?
B. 단답형 (문법)
- 함수를 정의할 때 사용하는 키워드는?
- 함수에서 값을 반환할 때 사용하는 키워드는?
- 모듈의 모든 함수를 확인하는 함수는?
C. 서술형 (코드 작성)
- 팩토리얼을 구하는 재귀함수를 작성하시오
- 가변 매개변수를 사용하여 여러 숫자의 합을 구하는 함수를 작성하시오
- 람다함수와 map()을 사용하여 리스트의 모든 원소를 제곱하는 코드를 작성하시오
D. 코드 분석 (실행 결과 예측)
x = 10
def func():
global x
x = 20
return x
print(x) # 결과는?
print(func()) # 결과는?
print(x) # 결과는?
🔍 9. 자주 틀리는 함정 포인트
⚠️ 주의사항 체크리스트
- [ ] 함수 정의 ≠ 함수 실행 (def는 정의만, 호출해야 실행)
- [ ] 지역변수 우선순위 (같은 이름이면 지역변수가 우선)
- [ ] global 키워드 (전역변수 수정 시 반드시 필요)
- [ ] 가변 매개변수 순서 (*args 먼저, **kwargs 나중에)
- [ ] return 이후 코드 (실행되지 않음)
- [ ] 재귀함수 종료조건 (무한루프 방지 필수)
- [ ] 람다함수 제한 (한 줄 표현식만 가능)
- [ ] yield vs return (yield는 함수 종료하지 않음)
💡 10. 암기 팁
🧠 외우기 쉬운 구문
- 함수 정의: "def 함수명(매개변수): return 반환값"
- 전역변수: "global 변수명"
- 가변 매개변수: "*args는 튜플, **kwargs는 딕셔너리"
- 람다함수: "lambda 매개변수: 표현식"
- 재귀함수: "종료조건 + 자기호출"
📝 시험 전 마지막 체크
- 함수 기본 구조 5번 손으로 써보기
- 지역변수/전역변수 예제 3개씩 만들어보기
- 매개변수 4가지 방식 각각 예제 작성
- 람다함수로 간단한 계산 함수 5개 만들기
- 재귀함수 팩토리얼 코드 외우기
🎯 최종 핵심 정리
순위 | 개념 | 중요도 | 암기 포인트 |
1 | 함수 정의/호출 | ⭐⭐⭐⭐⭐ | def, return, 호출 방법 |
2 | 지역/전역변수 | ⭐⭐⭐⭐⭐ | global 키워드, 우선순위 |
3 | 매개변수 전달 | ⭐⭐⭐⭐ | *args, **kwargs |
4 | 모듈 import | ⭐⭐⭐⭐ | import 방법 4가지 |
5 | 람다함수 | ⭐⭐⭐ | lambda 문법, map() 활용 |
6 | 재귀함수 | ⭐⭐⭐ | 종료조건, 팩토리얼 |
7 | 제너레이터 | ⭐⭐ | yield 키워드 |
🔥 시험 직전 마지막 점검: 위 7가지 개념을 각각 예제와 함께 설명할 수 있다면 합격! 🔥