..

파이썬에서 *args와 **kwargs 쓰는 법

저와 같이 일하는 한 분이 코드를 정말 잘 짭니다. 그분은 *args와 **kwargs를 자주 쓰시는데요, 정확히 언제 써야 하는지 늘 궁금했습니다.

좋은 글이 있어서 번역해보았습니다.


원문: https://www.freecodecamp.org/news/args-and-kwargs-in-python/, Ashutosh Krishna

이 글에서는 *args와 **kwargs를 어떻게 쓰는지 예시와 함께 알아봅니다.

args AND kwargs.png

함수를 쓸 때, 우리는 종종 값을 넣어줍니다. 이러한 값을 함수의 인수 (function arguments)라고 합니다.

인수 (function arguments)의 문제점

두 수를 더하는 함수를 정의해봅시다. 아래와 같이 쓸 수 있죠.

def add(x, y):
    return x+y

print(add(2,3))

결과:

5

세 개의 수를 더하고 싶다면 어떻게 할까요? 간단합니다. 세 개의 인수를 받아 더하도록 함수를 수정하면 됩니다.

def add(x, y, z):
    return x+y+z

print(add(2, 3, 5))

결과:

10

간단하죠? 하지만 다시 두 개의 수를 더해야 하면 어쩌죠? 수정한 함수가 제대로 동작할까요? 봅시다.

def add(x, y, z):
    return x+y+z

print(add(2, 3))

결과:

Traceback (most recent call last):
  File "D:\Quarantine\Test\Blog-Codes\args-kwargs\main.py", line 14, in <module>
    print(add(2, 3))
TypeError: add() missing 1 required positional argument: 'z'

문제가 뭔지 알겠나요?

문제는 인수의 개수가 바뀔 때 발생합니다. 인수 개수가 변할 때마다 함수를 계속 수정해야 할까요? 당연히 아닙니다. 분명 다른 방법이 있을 겁니다. 바로 여기서 *args와 **kwargs가 등장합니다. 인수의 개수가 불확실할 때 우리는 *args와 **kwargs를 씁니다.

파이썬에서 *args 쓰는 방법

*args는 키워드 없는 인수 (non-keyword arguments)의 개수가 변할 때 사용합니다. 함수에 입력되는 매개변수 (parameter)를 쓸 때에는 이름 전에 별표(*)를 써야 합니다 (아래 코드 첫째 줄).

def add(*args):
    print(args, type(args))

add(2, 3)

결과:

(2, 3) <class 'tuple'>

이렇게 함수 안에서 인수 (argument)는 튜플 타입이 되며, *이 없어진 것을 제외하면 동일한 이름을 가지게 됩니다.

이제 add() 함수가 인수를 개수 상관 없이 받을 수 있도록 수정해봅시다.

def add(*numbers):
    total = 0
    for num in numbers:
        total += num
    return total

print(add(2, 3))
print(add(2, 3, 5))
print(add(2, 3, 5, 7))
print(add(2, 3, 5, 7, 9))

결과:

5
10
17
26

인수 이름이 꼭 args일 필요는 없다는 점에 주목해주세요. 어떤 이름을 써도 됩니다. 위의 코드에선 numbers입니다. 하지만 *args를 이름으로 쓰는 게 일반적입니다.

파이썬에서 **kwargs 쓰는 방법

**kwargs 는 키워드 인수 (keyword arguments)의 개수가 변할 때 사용합니다. 함수에 입력되는 매개변수 (parameter)를 쓸 때에는 이름 전에 별표(*) 두 개를 써서 인수의 종류를 나타내줍니다 (아래 코드 첫째줄).

def total_fruits(**kwargs):
    print(kwargs, type(kwargs))

total_fruits(banana=5, mango=7, apple=8)

결과:

{'banana': 5, 'mango': 7, 'apple': 8} <class 'dict'>

이번에는 인수가 딕셔너리 (dictionary) 타입으로 넘겨졌고, 함수 안에서 **이 없어진 것을 제외하면 똑같은 이름을 가지게 되었습니다.

이제 총 과일 개수를 계산하도록 total_fruits() 함수를 완성해봅시다.

def total_fruits(**fruits):
    total = 0
    for amount in fruits.values():
        total += amount
    return total

print(total_fruits(banana=5, mango=7, apple=8))
print(total_fruits(banana=5, mango=7, apple=8, oranges=10))
print(total_fruits(banana=5, mango=7))

결과:

20
30
12

인수 이름이 꼭 kwargs일 필요는 없다는 점에 주목해주세요. 아까와 마찬가지로 아무 이름이나 쓸 수 있습니다. 위의 코드에선 fruits입니다. 하지만 **kwargs를 이름으로 쓰는 게 일반적입니다.

결론

이 글에서는 파이썬의 특별한 키워드인 *args와 **kwargs를 알아보았습니다. 인수의 개수가 바뀔 때나 키워드 인수의 개수가 바뀔 때 각각 *args와 **kwargs를 통해 함수를 유연하게 쓸 수 있습니다.

읽어주셔서 감사합니다!

이 글에 나오는 코드는 여기에서 확인할 수 있습니다.