본문으로 건너뛰기

기본값과 키워드 인자

파이썬 목차함수레슨 41 / 59

목차

매개변수에 기본값(default value)을 정해 두면 부를 때 그 인자를 빼도 됩니다. 인자를 이름=값 꼴로 넘기면 적은 차례와 상관없이 이름이 같은 매개변수와 짝지어지는데, 이런 인자를 키워드 인자(keyword argument)라고 합니다.

매개변수와 인자에서 인자를 하나만 넘긴 order(drink)는 qty가 붙을 값이 없어 TypeError로 멈췄습니다. 주문은 대부분 한 잔이니 qty에 기본값 1을 정해 두면 빠진 자리를 그 값이 채웁니다. 매개변수가 많아 차례를 외우기 어려울 때는 키워드 인자로 이름을 붙여 넘깁니다.

10단계 중 1단계. 기본값이 있는 함수를 인자 하나로 부르는 코드입니다.

1기본값 — 인자를 빼면 쓰는 값

그림의 첫 장면 코드에 부르기를 하나 더 붙였습니다.

def order(item, qty=1):
    print(item, qty)


order('커피')
order('라테', 2)
실행 결과
커피 1
라테 2

1번 줄의 qty=1이 기본값입니다. 매개변수 이름 뒤에 = 기호와 값을 적습니다. 5번 줄은 인자가 하나라 새 함수 칸에서 item만 '커피'에 붙고, 짝지을 인자가 없는 qty는 기본값 1에 붙습니다(규칙 5). 6번 줄은 qty가 넘긴 2에 붙습니다. 기본값은 인자를 넘기지 않았을 때만 쓰입니다. 기본값이 없는 item은 늘 넘겨야 합니다.

2키워드 인자 — 이름대로 짝짓는다

인자를 이름=값 꼴로 넘기면 그 이름의 매개변수와 짝지어집니다. 지금까지 쓴 인자는 매개변수와 인자에서 본 위치 인자로, 적은 차례대로 짝지어졌습니다. 그림의 둘째 장면 코드에 한 줄을 더 붙였습니다.

def order(item, qty=1):
    print(item, qty)


order(qty=3, item='녹차')
order('녹차', qty=3)
실행 결과
녹차 3
녹차 3

5번 줄은 qty를 먼저 썼지만 이름대로 짝지어져 item은 '녹차'에, qty는 3에 붙습니다. 6번 줄처럼 섞어 쓸 수도 있습니다. '녹차'는 첫째 자리라 item에, qty는 이름으로 3에 붙습니다. 섞을 때는 위치 인자를 앞에 둡니다 — 키워드 인자 뒤에 위치 인자를 두면 실행하기 전에 문법 오류가 납니다.

def order(item, qty=1):
    print(item, qty)


name = '녹차'
order(qty=3, name)
실행 결과
  File "main.py", line 6    order(qty=3, name)                     ^SyntaxError: positional argument follows keyword argument

맨 아래 줄은 '위치 인자가 키워드 인자 뒤에 왔다'는 뜻입니다. 위치 인자는 앞에서부터 차례로 짝지어지므로, 키워드 인자 뒤에는 쓸 수 없게 정해 두었습니다. 문법 오류라 5번 줄도 실행되지 않습니다.

3이미 쓴 키워드 인자 — print의 sep와 end

print로 출력하기의 sep와 end도 키워드 인자였습니다. 넘기지 않으면 기본값(빈칸 하나와 줄바꿈)이 쓰입니다. 아래 두 줄은 무엇을 찍을까요?

print('커피', '라테', '-')
print('커피', '라테', sep='-')
실행 결과 보기
실행 결과
커피 라테 -
커피-라테

예상과 다르면 그곳이 배울 곳입니다. 1번 줄의 '-'는 사이 글자가 아니라 셋째로 찍을 값으로 넘어갔습니다. print는 찍을 값을 몇 개든 위치 인자로 받습니다. 그래서 sep와 end는 2번 줄처럼 이름=값 꼴로만 넘길 수 있습니다.

값을 몇 개든 받는 함수는 매개변수 앞에 *를 붙여(*args) 만들지만, 이 과목에서는 쓰지 않습니다. sorted의 reverse=True도 키워드 인자입니다. 이름 없는 함수 lambda에서는 sorted에 key=로 함수를 넘깁니다.

예제

할인만 키워드로 넘기기

잔 수와 할인 금액에 기본값을 둔 계산 함수입니다.

def pay(price, qty=1, off=0):
    return price * qty - off


print(pay(4000))
print(pay(4000, 3))
print(pay(4000, off=500))
실행 결과
4000
12000
3500

7번 줄은 가운데 qty를 건너뛰고 off만 넘겼습니다. 키워드 인자로는 앞의 기본값을 그대로 둔 채 뒤의 매개변수 하나만 고를 수 있습니다.

할인을 위치 인자로 넘기면

같은 함수에 할인 500원을 위치 인자로 넘겼습니다. 무엇이 찍힐까요?

def pay(price, qty=1, off=0):
    return price * qty - off


print(pay(4000, 500))
실행 결과 보기
실행 결과
2000000

예상과 다르면 그곳이 배울 곳입니다. 3500을 예상했다면, 500이 뜻에 맞는 off를 찾아간다고 본 것입니다. 위치 인자는 적은 차례대로 짝지어집니다. qty가 둘째 자리의 500에 붙어, 4000원짜리 500잔 값 4000 * 500 - 0이 나왔습니다. 파이썬은 500이 할인 금액이라는 뜻을 모릅니다(규칙 6). 할인으로 넘기려면 off=500처럼 이름을 붙입니다.

자주 틀리는 곳

틀린 생각: 위치 인자는 뜻에 맞는 매개변수를 찾아 짝지어진다.

사람에게는 할인 금액이 off로 가는 것이 자연스럽습니다. 파이썬은 인자의 뜻을 보지 않고 자리만 셉니다.

def pay(price, qty=1, off=0):
    return price * qty - off


print(pay(4000, 500))
print(pay(4000, off=500))
실행 결과
2000000
3500

qty가 둘째 자리의 위치 인자 500에 붙고, off=500이라고 써야 off가 500에 붙습니다.

맞는 규칙: 파이썬은 인자의 뜻을 모르고 위치 인자는 적은 차례대로, 키워드 인자는 이름대로 짝짓습니다. 기본값을 건너뛰고 뒤의 매개변수에 넘길 때는 키워드 인자로 씁니다(규칙 6).

틀린 생각: 기본값이 있는 매개변수를 앞에 두어도 된다.

매개변수마다 이름이 있으니 아무 차례로 적어도 짝지어질 것 같습니다. 파이썬은 이런 정의를 실행하기 전에 막습니다.

def order(qty=1, item):
    print(item, qty)


order('커피')
실행 결과
  File "main.py", line 1    def order(qty=1, item):                     ^^^^SyntaxError: parameter without a default follows parameter with a default

파이썬 3.11에서는 맨 아래 줄의 설명 문구가 조금 다르게 찍히지만 오류 이름과 뜻은 같습니다.

맨 아래 줄은 '기본값 없는 매개변수가 기본값 있는 매개변수 뒤에 왔다'는 뜻입니다. 이대로라면 order('커피')에서 앞의 qty가 '커피'에 붙고 item은 빈 채로 남습니다.

맞는 규칙: 위치 인자가 앞에서부터 짝지어지므로, 기본값이 있는 매개변수는 기본값이 없는 매개변수 뒤에 둡니다.

확인 문제

1. 1절 코드에서 qty의 기본값을 2로 바꿨습니다. 무엇이 찍히는지 두 줄을 글자 그대로 쓰세요.

def order(item, qty=2):
    print(item, qty)


order('커피')
order('라테', 1)
힌트

5번 줄과 6번 줄에서 qty와 짝지을 인자가 있는지 따로 봅니다.

정답
실행 결과
커피 2
라테 1

5번 줄은 qty와 짝지을 인자가 없어 기본값 2에 붙고, 6번 줄은 넘긴 1에 붙습니다. 흔한 오답은 둘째 줄을 라테 2로 쓰는 것입니다. 기본값이 넘긴 인자보다 앞선다고 본 것입니다. 기본값은 인자를 넘기지 않았을 때만 쓰입니다.

2. 빈칸을 채워 pay(4000)은 4000을, pay(4000, 2)는 8000을 돌려주게 하세요.

# 1. 받을 값 정하기
def pay(price, ____):
    # 2. 계산하기
    total = price * qty
    # 3. 돌려주기
    return total


print(pay(4000))
print(pay(4000, 2))
힌트

4번 줄이 쓰는 qty가 어느 값에 붙는지, 9번 줄과 10번 줄의 부르기를 따로 따라가 봅니다.

정답

qty=1입니다.

# 1. 받을 값 정하기
def pay(price, qty=1):
    # 2. 계산하기
    total = price * qty
    # 3. 돌려주기
    return total


print(pay(4000))
print(pay(4000, 2))
실행 결과
4000
8000

9번 줄은 qty와 짝지을 인자가 없어 기본값 1에 붙고, 10번 줄은 넘긴 2에 붙습니다.

다르게 써도 되는 곳: qty = 1처럼 = 앞뒤를 띄워도 돌지만, 기본값과 키워드 인자의 =는 붙여 쓰는 것이 파이썬 문서(PEP 8)가 권하는 꼴입니다.

흔한 오답은 기본값 없이 qty만 쓰는 것입니다. 그러면 9번 줄에서 qty가 붙을 값이 없어 TypeError로 멈춥니다(꼭 있어야 할 인자 qty가 빠졌다는 오류 — 매개변수 레슨의 대표 오류와 같습니다). 인자를 빼면 qty가 저절로 1이 된다고 본 것입니다.

3. 장보기 목록을 찍는 함수입니다. 무엇이 찍히는지 세 줄을 글자 그대로 쓰세요.

def buy(item, qty=1, unit='개'):
    print(item, qty, unit)


buy('사과', 3)
buy('우유', '병')
buy('달걀', unit='판')
힌트

6번 줄의 인자 둘이 각각 몇째 자리인지 세어 봅니다.

정답
실행 결과
사과 3 개
우유 병 개
달걀 1 판

6번 줄에서는 qty가 둘째 자리의 '병'에 붙고, unit은 기본값 '개'에 붙습니다. 7번 줄은 qty를 건너뛰고 unit만 이름으로 넘겼습니다. 흔한 오답은 둘째 줄을 우유 1 병으로 쓰는 것입니다. 위치 인자가 뜻에 맞는 매개변수를 찾아간다고 본 것입니다. 위치 인자는 적은 차례대로 짝지어집니다(규칙 6).

7번 줄 off=500 뒤에 인자 qty=2를 더 넘기면 찍히는 줄을 모두 봅니다.

처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

파이썬 목차로