Functions. & Module Control of Flow
1. 함수(Function) – “코드를 이름 붙여서 재사용하기”
1-1. 함수가 뭔데?
- 반복해서 쓰는 코드 덩어리에
이름을 붙여서 모아 놓은 것. - 한 번 정의해 두면 여러 번 호출해서 재사용할 수 있음.
- “입력 ➜ 처리 ➜ 출력”을 한 덩어리로 묶은 느낌.
def add(a, b): # add 라는 이름의 함수 정의
result = a + b # 처리
return result # 결과 돌려주기
print(add(3, 5)) # 함수 호출 => 8
이렇게 해 두면, 3+5, 10+20, 100+200… 매번 코드를 새로 쓰지 않고 add()만 계속 호출하면 됨.
1-2. 함수 기본 구조
함수는 항상 이 네 가지 구성을 가진다고 생각하면 편함.
def 함수이름(매개변수들):
"""여기에 함수 설명(Docstring)을 작성한다."""
# 함수 본문(body) – 실제로 일하는 코드
...
return 결과값
def키워드- 함수 이름
- 괄호 안 매개변수(parameter)
- 함수 몸통(body) +
return(선택)
1-3. 함수 호출하기
정의만 해두면 아무 일도 안 일어남.
“이제 일해줘!”라고 시키려면 호출(call) 해야 함.
def greet(name):
print(f"{name}님 안녕하세요!")
greet("혜령") # 여기서 실제로 함수가 실행됨
greet("홍길동")
2. return vs print – 진짜 자주 헷갈리는 포인트
2-1. return은 “값을 돌려주기”
def square(x):
return x * x
result = square(3)
print(result) # 9
return은 함수 밖으로 값을 돌려주는 역할.return을 만나면 함수는 그 즉시 종료됨.- 돌려준 값은 변수에 담거나, 다른 계산에 바로 쓸 수 있음.
2-2. print는 “눈에 보여주기”
def square_and_print(x):
print(x * x)
result = square_and_print(3)
print("result:", result) # result: None
print는 콘솔에 글자를 찍는 것일 뿐,- 함수의 “결과값”이 아님.
- 아무
return이 없으면 기본적으로None을 돌려줌.
정리
- “계산 결과를 다시 써먹고 싶다” →
return- “그냥 화면에 보여주기만 하면 된다” →
3. 매개변수(Parameter)와 인자(Argument)
3-1. 용어 정리
- 매개변수(parameter)
- 함수를 정의할 때 괄호 안에 적는 이름
- 함수 안에서 쓰는 변수 역할
- 인자(argument)
- 함수를 호출할 때 실제로 넣어주는 값
def add(a, b): # a, b → 매개변수(parameter)
return a + b
add(3, 5) # 3, 5 → 인자(argument)
3-2. 다양한 인자 종류
1) 위치 인자(Positional Arguments)
- 순서대로 매개변수에 값이 들어감.
- 기본적인 호출 방식.
def greet(name, age):
print(f"{name}은 {age}살입니다.")
greet("Alice", 25) # name="Alice", age=25
2) 기본값 인자(Default Arguments)
- 매개변수에 기본값을 미리 정해둘 수 있음.
- 안 넣으면 기본값, 넣으면 넣은 값 사용.
def greet(name, age=20):
print(f"{name}은 {age}살입니다.")
greet("Bob") # Bob은 20살입니다.
greet("Charlie", 30) # Charlie는 30살입니다.
3) 키워드 인자(Keyword Arguments)
매개변수이름=값형태로 전달.- 순서와 상관없이 알맞은 매개변수에 들어감.
def greet(name, age):
print(f"{name}은 {age}살입니다.")
greet(age=30, name="Dave")
4) 가변 위치 인자 *args
- 인자의 개수를 유동적으로 받고 싶을 때.
- 함수 안에서
tuple로 사용.
def add_all(*numbers):
print(numbers, type(numbers)) # (1, 2, 3) <class 'tuple'>
return sum(numbers)
print(add_all(1, 2, 3, 4))
5) 가변 키워드 인자 **kwargs
키=값형태의 인자를 여러 개 받을 때.- 함수 안에서
dict로 사용.
def print_info(**info):
print(info)
print_info(name="혜령", age=25, city="Daegu")
# {'name': '혜령', 'age': 25, 'city': 'Daegu'}
6) 섞어서 쓸 때 순서 규칙
항상 이 순서를 지켜야 함:
일반 위치 인자 → args → 기본값 인자 → *kwargs
def func(pos1, *args, default_arg=0, **kwargs):
...
4. 재귀 함수(Recursive Function)
4-1. 개념
- 함수 안에서 자기 자신을 다시 호출하는 함수.
- 큰 문제를 같은 형태의 더 작은 문제들로 쪼개어 해결할 때 사용.
4-2. 핵심: “기저 사례(Base Case)”가 꼭 있어야 함
- 무한히 자기 자신을 부르면 프로그램이 끝나지 않고 오류 남.
- “여기까지 오면 더 이상 재귀 호출을 안 한다” 라는 조건을 꼭 넣어야 함.
4-3. 예시: 팩토리얼 n!
n! = n * (n-1) * (n-2) * ... * 1
재귀 정의:
0! = 1n! = n * (n-1)!(n > 0 일 때)
def factorial(n):
if n == 0: # 기저 사례
return 1
return n * factorial(n - 1)
print(factorial(5)) # 120
- 함수가 호출될 때마다
n이 1씩 줄어들다가0이 되면 재귀 종료.
5. 스코프(Scope)와 LEGB 규칙
5-1. 스코프란?
- 변수 이름을 찾는 범위.
- “어디까지 이 변수 이름을 알아볼 수 있냐?”의 문제.
5-2. 파이썬의 스코프 4단계 (LEGB)
이 순서대로 변수를 찾음:
- L – Local: 현재 함수 내부
- E – Enclosing: 바깥 함수(중첩 함수에서)
- G – Global: 모듈(파일) 전체
- B – Built-in: 파이썬이 원래 가지고 있는 이름들 (
len,sum등)
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print(x)
inner()
outer() # 'local'
내부에서 이름을 찾을 때는 가까운 스코프부터 먼 스코프 순으로 찾는다고 이해하면 됨.
5-3. global 키워드
- 함수 안에서 전역 변수 값을 바꾸고 싶을 때 사용.
count = 0
def increase():
global count
count += 1
increase()
print(count) # 1
- 너무 많이 쓰면 코드 이해하기 힘들어짐 → 가능한 한 지역 변수와 return 값으로 처리하는 습관 들이기.
6. 함수 스타일 & 단일 책임 원칙
6-1. 함수 이름 짓기
- 소문자 + 언더스코어(
snake_case)get_username,calculate_total_price
- 이름만 봐도 무슨 일을 하는지 알 수 있게 짓기.
def calc_total_price(price, tax):
return price + tax
6-2. 단일 책임 원칙(Single Responsibility Principle)
한 함수는 한 가지 일만 하도록.
나쁜 예 (여러 일을 한 함수에 다 우겨 넣은 경우):
def handle_user_signup(user_data):
# 1) 입력 검증
# 2) DB 저장
# 3) 이메일 발송
# 4) 로그 기록
...
좋은 방향:
validate_user_datasave_usersend_welcome_emaillog_signup
처럼 여러 개의 작은 함수로 나누기.
테스트도 쉽고, 유지보수도 쉬워짐.
7. Packing & Unpacking (*, **)
7-1. 패킹(Packing)
- 여러 값을 하나의 변수에 묶어서 담기.
packed = 1, 2, 3, 4
print(packed) # (1, 2, 3, 4) 튜플
가변 인자에서의 패킹:
def my_func(*args):
print(args)
my_func(1, 2, 3) # (1, 2, 3)
7-2. 언패킹(Unpacking)
- 묶여 있는 값을 다시 여러 변수로 풀기.
a, b, c = (1, 2, 3)
print(a, b, c) # 1 2 3
*를 이용한 언패킹:
numbers = [1, 2, 3, 4, 5]
first, *middle, last = numbers
print(first) # 1
print(middle) # [2, 3, 4]
print(last) # 5
딕셔너리도 **로 언패킹해서 함수 인자로 넘길 수 있음.
def introduce(name, age):
print(name, age)
data = {"name": "혜령", "age": 25}
introduce(**data) # introduce(name="혜령", age=25)
8. 모듈(Module) – 파일 단위로 코드 묶기
8-1. 모듈이란?
- 하나의
.py파일 = 하나의 모듈. - 여러 함수를 파일로 묶어놓은 것.
- 다른 파일에서 가져다 쓸 수 있음.
# my_math.py
def add(a, b):
return a + b
# main.py
import my_math
print(my_math.add(3, 5))
8-2. import 사용법
- 기본
import
import math
print(math.pi)
print(math.sqrt(9))
from ~ import ~
from math import sqrt, pi
print(pi)
print(sqrt(9))
- 별칭 붙이기
import math as m
print(m.sqrt(16))
8-3. 사용자 정의 모듈 만들기
- 새 파일에 함수/변수 정의
- 같은 폴더에서
import해서 사용
# utils.py
def greet(name):
print(f"Hello, {name}!")
# main.py
import utils
utils.greet("혜령")
9. 패키지(Package) – 폴더 레벨 묶음
- 모듈 여러 개를 모아둔 폴더 개념.
- 보통 이런 구조:
my_package/
__init__.py
math_tools.py
string_tools.py
사용 예시:
from my_package import math_tools
math_tools.add(1, 2)
10. 외부 패키지와 pip
10-1. pip란?
- 파이썬에서 외부 라이브러리를 설치해주는 도구.
pip install requests
pip install SomePackage==1.2.3
10-2. 설치 후 사용 예
import requests
response = requests.get("https://example.com")
print(response.status_code)
11. 제어문(Control Statement) – 조건과 반복
11-1. 조건문 if / elif / else
score = int(input("점수 입력: "))
if score >= 90:
print("A")
elif score >= 80:
print("B")
else:
print("C 이하")
- 위에서부터 차례대로 조건을 검사.
True인 첫 번째 블록만 실행되고 나머지는 무시.
11-2. 반복문 for
- 반복 가능한(iterable) 객체의 각 요소를 하나씩 꺼내며 반복.
students = ["Alice", "Bob", "Charlie"]
for student in students:
print(student)
range()와 함께 쓰기:
for i in range(5): # 0,1,2,3,4
print(i)
딕셔너리 순회:
my_dict = {"a": 1, "b": 2}
for key in my_dict:
print(key, my_dict[key])
11-3. 반복문 while
- 조건이 참인 동안 반복.
n = 1
while n <= 5:
print(n)
n += 1
- 조건이 언젠가
False가 되도록 코드를 써야 함 (무한 루프 주의).
12. 반복 제어: break, continue, pass
12-1. break – 반복문 강제 종료
for n in range(1, 11):
if n == 5:
break
print(n) # 1 2 3 4 까지만 출력
12-2. continue – 이번 회차만 건너뛰기
for n in range(1, 6):
if n % 2 == 0:
continue
print(n) # 홀수만 출력: 1 3 5
12-3. pass – “아직 할 일 없음”
def todo():
pass # 나중에 구현할 예정
for _ in range(3):
pass # 자리만 만들어 둠
13. map, zip, enumerate – 자주 쓰이는 내장 함수
13-1. map(function, iterable)
- 각 요소에 함수를 적용해서 새 시퀀스를 만드는 도구.
numbers = [1, 2, 3, 4]
def square(x):
return x * x
result = list(map(square, numbers))
print(result) # [1, 4, 9, 16]
람다와 함께 자주 사용:
result = list(map(lambda x: x * x, numbers))
13-2. zip(*iterables)
- 여러 시퀀스를 같은 인덱스끼리 묶어주는 함수.
names = ["A", "B", "C"]
scores = [100, 90, 80]
for name, score in zip(names, scores):
print(name, score)
# A 100
# B 90
# C 80
13-3. enumerate(iterable, start=0)
- 반복하면서 인덱스와 값을 같이 받고 싶을 때.
fruits = ["apple", "banana", "cherry"]
for idx, fruit in enumerate(fruits, start=1):
print(idx, fruit)
# 1 apple
# 2 banana
# 3 cherry
마무리 정리
- 함수는 반복되는 작업을 이름 붙여서 재사용하는 도구.
return은 값을 돌려주는 것,print는 보여주기만 하는 것.- 매개변수/인자 개념 구분 & 위치·기본값·키워드·가변 인자까지 이해하기.
- 재귀 함수는 항상 기저 사례를 넣어서 종료 조건 만들기.
- 변수 이름을 찾는 순서는 LEGB.
- 한 함수에는 한 가지 일만 – 단일 책임 원칙.
- 모듈은 파일, 패키지는 폴더.
import/from ~ import ~자유자재. - 조건문/반복문으로 흐름을 제어하고,
break/continue로 흐름 세밀하게 조정. map,zip,enumerate는 자료구조를 우아하게 다루는 삼신기 느낌으로 익혀두기.
'Language& Framework > Python' 카테고리의 다른 글
| OOP (1) | 2025.12.12 |
|---|---|
| Data Structure (0) | 2025.12.12 |
| Python Basic Syntax (0) | 2025.12.11 |