이번 편의 목표: 매개변수와 return으로 계산과 출력을 분리합니다.

합계를 계산하는 코드를 여러 곳에 복사하면 수정도 여러 번 해야 합니다. 함수는 한 가지 일을 묶어 이름을 붙이고, 필요할 때 호출하는 방법입니다. 이름이 생기면 프로그램을 더 큰 단위로 읽을 수 있습니다.

입력을 받고 결과를 돌려준다

Python
def calculate_total(price, quantity=1):
    """가격과 수량으로 총액을 계산한다."""
    return price * quantity

def format_won(amount):
    return f"{amount:,}원"

first = calculate_total(4500, 2)
second = calculate_total(price=8000)
print(format_won(first))
print(format_won(second))

`def`는 함수를 정의합니다. 괄호 안의 `price`, `quantity`는 호출할 때 받을 매개변수입니다. 호출할 때 넘기는 `4500`, `2` 같은 값은 인수라고 부릅니다. `quantity=1`은 생략했을 때 사용할 기본값입니다.

함수 정의의 본문은 정의만으로 계산되지 않습니다. `calculate_total(4500, 2)`처럼 호출할 때 실행됩니다. 결과는 `9000`이고, `return`이 그 값을 호출한 곳으로 돌려줍니다. `format_won()`은 받아온 숫자를 표시할 문자열로 바꿉니다.

print와 return은 다른 일이다

`print()`는 화면에 보여 줍니다. `return`은 값을 돌려줘서 다른 계산에 사용할 수 있게 합니다. 계산 함수가 결과를 `print()`만 하고 끝나면 호출한 쪽에서 받은 반환값은 `None`입니다. 그 값을 다시 숫자처럼 더할 수는 없습니다.

합계 계산 함수는 숫자를 반환하고, 화면 출력은 바깥에서 하게 만들면 파일 저장이나 테스트에서도 재사용하기 쉽습니다. 함수 안에서 `input()`까지 받으면 호출할 때마다 사람이 입력해야 합니다. 입력·계산·출력을 나누는 것이 작은 프로그램에서도 도움이 되는 이유입니다.

이름과 인수를 분명하게

`calculate_total(price=4500, quantity=2)`처럼 인수 이름을 적으면 순서를 헷갈릴 가능성이 줄어듭니다. 기본값이 있는 매개변수는 일반적으로 기본값 없는 매개변수 뒤에 둡니다. 정의하지 않은 이름의 인수를 넘기거나 필수 인수를 빠뜨리면 `TypeError`가 발생합니다.

함수 첫 줄의 설명 문자열은 독스트링입니다. 사용 방법과 반환하는 값의 뜻을 짧게 적습니다. 모든 줄에 한국어 주석을 붙이기보다 함수 이름과 매개변수 이름으로 의도가 드러나게 만드는 편이 유지하기 쉽습니다.

너무 큰 함수를 나누는 기준도 이름입니다. “입력을 받고 검증하고 파일에 쓰고 보고서를 출력한다”는 설명이 필요하면 여러 함수가 섞여 있을 가능성이 큽니다. 우선 계산 하나를 떼어내는 것부터 시작하세요.

직접 해 보기

금액 목록을 받아 평균을 반환하는 `average()` 함수를 만드세요. 빈 목록이면 이번 연습에서는 `0`을 반환하도록 정합니다.

해설

Python
def average(amounts):
    if not amounts:
        return 0
    return sum(amounts) / len(amounts)

print(average([1000, 2000, 3000]))
print(average([]))

결과는 `2000.0`, `0`입니다. 빈 자료를 0으로 표현할지 별도 값으로 표현할지는 실제 업무의 규칙입니다. 함수의 동작을 먼저 정하고 코드로 옮기는 습관을 들이세요.