
지난 글에서는 딕셔너리와 집합으로 데이터를 알맞게 묶는 방법을 배웠습니다. 그런데 주문 금액을 계산하는 코드가 프로그램 곳곳에 열 번 나온다면, 할인 규칙이 바뀔 때 열 군데를 모두 고쳐야 할까요?
함수는 자주 하는 일을 하나의 이름으로 묶는 작은 자동판매기와 같습니다. 재료를 넣으면 정해 둔 순서대로 처리하고 결과를 돌려줍니다. 코드를 짧게 만드는 기술이라기보다, 복잡한 프로그램을 이해할 수 있는 작은 역할로 나누는 방법입니다.
이번 글에서는 검색할 때 자주 만나는 파이썬 함수 만들기, def, 매개변수와 인수, return을 쉬운 예제로 연결합니다. 특히 화면에는 값이 잘 출력됐는데 변수에는 왜 None이 들어가는지, print()와 return의 차이까지 확실하게 정리해 보겠습니다.
함수는 왜 필요할까?
카페 주문의 총액을 여러 번 계산한다고 가정해 보겠습니다.
price1 = 4500
count1 = 2
total1 = price1 * count1
print(f"첫 주문: {total1:,}원")
price2 = 3800
count2 = 3
total2 = price2 * count2
print(f"둘째 주문: {total2:,}원")
계산 방법은 같은데 값만 달라집니다. 주문이 늘어날수록 같은 코드가 반복되고, 할인 규칙을 추가할 때 빠뜨릴 곳도 늘어납니다.
함수로 역할을 묶으면 계산 규칙은 한곳에만 남습니다.
def calculate_total(price, count):
return price * count
print(calculate_total(4500, 2))
print(calculate_total(3800, 3))
9000
11400
calculate_total이라는 이름만 읽어도 무엇을 하는 코드인지 짐작할 수 있습니다. 계산식이 바뀌어도 함수 안을 한 번만 고치면 됩니다.
파이썬 함수 만들기: def 기본 문법
파이썬에서 직접 함수를 만들 때는 def로 시작합니다.
def 함수이름(매개변수):
실행할 코드
return 결과
def는 지금부터 함수를 정의한다는 뜻입니다.- 함수 이름은 그 역할을 설명하도록 짓습니다.
- 괄호 안의 매개변수는 함수가 받을 값을 나타냅니다.
- 콜론
:다음 줄부터 함수의 본문을 들여씁니다. return은 계산한 결과를 함수를 호출한 곳으로 돌려줍니다.
간단한 인사 함수를 만들어 보겠습니다.
def greet():
print("안녕하세요!")
greet()
greet()
안녕하세요!
안녕하세요!
함수를 정의한 것만으로 본문이 바로 실행되지는 않습니다. greet()처럼 괄호를 붙여 호출할 때마다 함수 안의 코드가 위에서 아래로 실행됩니다.
함수 정의와 호출의 실행 순서
다음 코드의 출력 순서를 먼저 예상해 보세요.
def make_message():
print("2. 함수 안")
print("1. 호출 전")
make_message()
print("3. 호출 후")
1. 호출 전
2. 함수 안
3. 호출 후
파이썬이 def를 만나면 함수의 내용을 기억해 둡니다. 실행 흐름이 make_message()에 도착하면 함수 안으로 잠시 이동하고, 본문이 끝나면 호출했던 다음 줄로 돌아옵니다.
함수 호출은 책에 꽂아 둔 책갈피와 비슷합니다. 함수 안의 일을 마치면 책갈피를 꽂아 둔 다음 줄로 돌아옵니다.
매개변수와 인수 차이
두 용어는 비슷하지만 사용되는 자리가 다릅니다.
def greet(name): # name은 매개변수
print(f"{name}님, 반갑습니다!")
greet("민지") # "민지"는 인수
- 매개변수(parameter): 함수를 정의할 때 값을 받을 이름
- 인수(argument): 함수를 호출할 때 실제로 전달하는 값
매개변수가 주문서의 빈칸이라면 인수는 그 빈칸에 실제로 적는 내용입니다. 일상적인 설명에서는 둘을 넓게 ‘인자’라고 부르기도 하지만, 코드의 흐름을 볼 때는 정의하는 자리와 호출하는 자리를 구분하면 이해가 쉽습니다.
매개변수가 여러 개일 때
필요한 값이 여러 개라면 쉼표로 구분합니다.
def introduce(name, hobby):
print(f"저는 {name}이고, 취미는 {hobby}입니다.")
introduce("서연", "그림 그리기")
호출할 때 전달한 값은 기본적으로 위치 순서대로 연결됩니다. 첫 번째 인수 "서연"은 name에, 두 번째 인수 "그림 그리기"는 hobby에 들어갑니다.
개수나 순서가 맞지 않으면 TypeError가 발생할 수 있습니다.
introduce("서연")
오류는 함수가 필요로 하는 두 값 가운데 하나가 빠졌다는 안내입니다. 함수의 괄호를 볼 때는 “몇 개를 어떤 순서로 받아야 하는가?”를 확인하세요.
return은 결과를 호출한 곳으로 돌려준다
return은 단순히 값을 화면에 보여 주는 명령이 아닙니다. 함수가 만든 결과를 호출한 곳에 전달합니다.
def calculate_total(price, count):
total = price * count
return total
order_total = calculate_total(4500, 2)
print(order_total)
print(order_total + 1000)
9000
10000
실행 흐름은 다음과 같습니다.
calculate_total(4500, 2)를 호출합니다.price에는 4500,count에는 2가 연결됩니다.- 함수 안에서
total을 계산합니다. return total이 9000을 호출한 자리로 돌려줍니다.- 반환된 9000이
order_total에 저장됩니다.
반환값은 변수에 저장하거나, 다른 계산에 쓰거나, 조건문에 넣을 수 있습니다. 이 재사용 가능성이 함수의 핵심입니다.
print와 return 차이: None이 나오는 이유
파이썬 함수를 처음 배울 때 가장 자주 만나는 함정입니다.
def add_print(a, b):
print(a + b)
result = add_print(4, 6)
print("저장된 값:", result)
10
저장된 값: None
첫 줄의 10은 함수 안의 print()가 화면에 보여 준 값입니다. 하지만 함수는 결과를 return하지 않았습니다. 파이썬 함수가 return 없이 끝나면 자동으로 None을 반환하므로 result에는 None이 저장됩니다.
계산 결과를 다시 사용하려면 다음처럼 작성합니다.
def add_return(a, b):
return a + b
result = add_return(4, 6)
print("저장된 값:", result)
저장된 값: 10
print()는 사람에게 값을 보여 줍니다.return은 프로그램의 다음 코드가 쓰도록 값을 돌려줍니다.
영수증 화면에 가격을 띄우는 일과 계산 결과를 장부에 넘기는 일이 서로 다른 것과 같습니다. 디버깅이나 안내에는 print()가 필요하고, 계산 결과를 재사용하려면 return이 필요합니다.
return을 만나면 함수는 즉시 끝난다
return은 값을 돌려주는 동시에 현재 함수의 실행을 종료합니다.
def check_age(age):
if age < 0:
return "나이는 음수가 될 수 없습니다."
return f"입력한 나이: {age}세"
print("이 문장은 실행되지 않습니다.")
print(check_age(-3))
print(check_age(20))
나이는 음수가 될 수 없습니다.
입력한 나이: 20세
음수가 들어오면 첫 번째 return에서 바로 함수를 빠져나옵니다. 마지막 return 아래의 print()도 실행되지 않습니다. 이렇게 잘못된 입력을 초기에 돌려보내면 코드가 깊게 중첩되는 것을 줄일 수 있습니다.
함수로 역할을 나누는 기준
모든 코드를 무조건 함수로 감싸면 오히려 이름만 늘어날 수 있습니다. 다음 질문 가운데 하나라도 “예”라면 함수로 나눌 좋은 후보입니다.
- 같은 코드가 여러 번 반복되는가?
- 한 덩어리의 역할을 짧은 이름으로 설명할 수 있는가?
- 계산 규칙이 나중에 바뀔 가능성이 있는가?
- 입력과 결과를 따로 시험해 보고 싶은가?
예를 들어 주문 프로그램을 계산과 출력 문장 생성 역할로 나눌 수 있습니다.
def calculate_total(prices):
total = 0
for price in prices:
total += price
return total
def make_receipt(total):
return f"결제 금액은 {total:,}원입니다."
orders = [4500, 3800, 5200]
total = calculate_total(orders)
receipt = make_receipt(total)
print(receipt)
결제 금액은 13,500원입니다.
앞에서 배운 리스트, 반복문, 누적 계산, f-string이 함수 안에서 하나의 역할로 정리되었습니다. calculate_total()은 계산만 하고, make_receipt()은 문장을 만드는 데 집중합니다.
좋은 함수 이름 짓기
함수 이름은 보통 동작을 나타내는 동사로 시작하면 읽기 쉽습니다.
calculate_total: 총액을 계산한다find_student: 학생을 찾는다is_even: 짝수인지 판단한다make_message: 메시지를 만든다
do_it(), func1()처럼 역할을 알 수 없는 이름은 본문을 열어 봐야 뜻을 알 수 있습니다. 함수가 하는 일을 한 문장으로 설명하기 어렵다면 너무 많은 역할을 맡고 있다는 신호일 수도 있습니다.
자주 하는 실수
함수를 정의만 하고 호출하지 않는 경우
def는 실행할 코드를 등록합니다. 결과를 보려면 function_name()처럼 호출해야 합니다.
함수 본문을 들여쓰지 않는 경우
콜론 다음 줄의 본문은 반드시 들여써야 합니다. 들여쓰기는 어느 코드가 함수에 속하는지를 나타냅니다.
print한 값을 반환했다고 생각하는 경우
화면에 값이 보였다고 반환된 것은 아닙니다. 호출 결과를 변수에 저장해야 한다면 return이 있는지 확인하세요.
return 아래에 실행할 코드를 쓰는 경우
return을 만나면 함수는 끝납니다. 같은 경로에서 그 아래에 있는 코드는 실행되지 않습니다.
매개변수와 인수의 개수를 맞추지 않는 경우
함수 정의의 괄호와 호출의 괄호를 함께 보면서 필요한 값의 개수와 순서를 확인하세요.
직접 바꿔 보며 확인하기
- 이름을 받아 인사 문장을 반환하는
make_greeting()함수를 만듭니다. - 두 수를 받아 더한 값을 반환하는
add()함수를 만듭니다. - 가격과 수량을 받아 총액을 반환하는
calculate_total()을 만들고 결과를 천 단위 쉼표로 출력합니다. - 숫자를 받아 짝수이면
True, 홀수이면False를 반환하는is_even()을 만듭니다. print()만 사용하는 덧셈 함수의 호출 결과를 변수에 저장해None을 직접 확인합니다.- 리스트를 받아 가장 큰 값을 찾는 함수를 반복문과 조건문으로 작성합니다.
함수를 만들기 전에 “무엇을 받고, 어떤 일을 하며, 무엇을 돌려줄까?”를 한 문장으로 적어 보세요. 이 세 가지가 분명하면 매개변수와 return의 자리도 자연스럽게 정해집니다.
정리
파이썬 함수는 관련된 코드를 하나의 이름으로 묶어 반복을 줄이고 역할을 나눕니다. def로 정의하고 괄호를 붙여 호출하며, 함수 본문은 들여씁니다.
매개변수는 함수를 정의할 때 값을 받을 이름이고, 인수는 호출할 때 전달하는 실제 값입니다. return은 결과를 호출한 곳으로 돌려주고 함수를 즉시 끝냅니다. 반면 print()는 값을 화면에 보여 줄 뿐이므로 return이 없는 함수의 호출 결과를 저장하면 None이 들어갑니다.
다음 글에서는 함수 안과 밖의 변수가 왜 다르게 움직이는지 알아봅니다. 지역 변수와 스코프, 기본 인자와 키워드 인자를 이해하면 함수를 더 안전하고 편리하게 설계할 수 있습니다.
참고 자료
7. Simple statements
A simple statement is comprised within a single logical line. Several simple statements may occur on a single line separated by semicolons. The syntax for simple statements is: Expression statement...
docs.python.org
'파이썬(Python)' 카테고리의 다른 글
| [Python(파이썬)] 스코프란? 지역·전역 변수와 기본 인자·키워드 인자 이해하기 (0) | 2026.08.20 |
|---|---|
| [Python(파이썬)] 딕셔너리 사용법과 set 중복 제거, 한 번에 이해하기 (0) | 2026.08.14 |
| [Python(파이썬)] 리스트와 튜플 차이? 추가·삭제·복사까지 쉽게 이해하기 (0) | 2026.08.13 |
| [Python(파이썬)] 문자열이란? 인덱싱·슬라이싱·메서드와 f-string 쉽게 이해하기 (0) | 2026.08.12 |
| [Python(파이썬)] while문이란? 종료 조건과 break·continue 쉽게 이해하기 (0) | 2026.08.11 |