개발 공부/Python

09_파이썬 함수와 모듈 마스터하기: 기본부터 심화까지 완벽 가이드!

squareegg 2025. 6. 9. 09:50

안녕하세요! 오늘은 파이썬 프로그래밍의 핵심 요소인 함수모듈에 대해 상세히 알아보겠습니다. 초보자도 쉽게 따라할 수 있도록 실제 예제와 함께 설명드릴게요!


🎯 이 장에서 만들 프로그램 미리보기 {#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)}")

🎯 핵심 정리

  1. 함수는 코드의 재사용성과 가독성을 높이는 핵심 도구
  2. 지역변수전역변수를 구분해서 사용하기
  3. 매개변수 전달 방식을 상황에 맞게 선택하기
  4. 모듈을 활용해 코드를 체계적으로 관리하기
  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. 객관식 (개념 이해)

  1. 다음 중 전역변수를 함수 내에서 수정할 때 사용하는 키워드는?
  2. *args와 **kwargs의 차이점은?
  3. 재귀함수에서 반드시 필요한 것은?

B. 단답형 (문법)

  1. 함수를 정의할 때 사용하는 키워드는?
  2. 함수에서 값을 반환할 때 사용하는 키워드는?
  3. 모듈의 모든 함수를 확인하는 함수는?

C. 서술형 (코드 작성)

  1. 팩토리얼을 구하는 재귀함수를 작성하시오
  2. 가변 매개변수를 사용하여 여러 숫자의 합을 구하는 함수를 작성하시오
  3. 람다함수와 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 매개변수: 표현식"
  • 재귀함수: "종료조건 + 자기호출"

📝 시험 전 마지막 체크

  1. 함수 기본 구조 5번 손으로 써보기
  2. 지역변수/전역변수 예제 3개씩 만들어보기
  3. 매개변수 4가지 방식 각각 예제 작성
  4. 람다함수로 간단한 계산 함수 5개 만들기
  5. 재귀함수 팩토리얼 코드 외우기

🎯 최종 핵심 정리

순위 개념 중요도 암기 포인트
1 함수 정의/호출 ⭐⭐⭐⭐⭐ def, return, 호출 방법
2 지역/전역변수 ⭐⭐⭐⭐⭐ global 키워드, 우선순위
3 매개변수 전달 ⭐⭐⭐⭐ *args, **kwargs
4 모듈 import ⭐⭐⭐⭐ import 방법 4가지
5 람다함수 ⭐⭐⭐ lambda 문법, map() 활용
6 재귀함수 ⭐⭐⭐ 종료조건, 팩토리얼
7 제너레이터 ⭐⭐ yield 키워드

🔥 시험 직전 마지막 점검: 위 7가지 개념을 각각 예제와 함께 설명할 수 있다면 합격! 🔥

728x90
반응형