파이썬에서 초급단계를 벗어나 중급 단계를 향해 달려가고 있는 필자는 처음에 *args와 **kwargs를 보고, 파이썬에도 포인터가 존재하는 줄 알았다.
파이썬을 처음 배울 때는 포인터라는 게 없다는 말을 듣고 정말 기뻤다. 포인터가 존재하는 다른 언어를 배울 때 정말 고생했기 때문이다. 그냥 개념 자체가 생소했고, 이해가 가지 않았다.
그런데 웬걸, 스택오버플로우를 어느 날과 다름없이 눈팅하고 있었던 나는 신기한 키워드를 두 개나 보게 되었다. 바로 *args와 **kwargs.
엥? 분명 파이썬에는 포인터 없다고 했는데 *(별표)는 뭐지?
오해해도 단단히 오해하고 있었다. 포인터가 아니었다 (휴~).
이번 포스팅에서는 파이썬에서 *args와 *kwargs가 무엇이고, 어떠한 역할을 하며, 어떨 때 쓰는지 알아보도록 하겠다.
*args란 무엇일까?
*args가 무엇인지 설명하기에 앞서, 파이썬으로 프로그램을 작성할 때 꼭 *args라고 작성할 필요는 없다. args는 변 수명이기 때문에 어떠한 변수명을 사용해도 무관하다. 앞에 *(별표)만 꼭 붙이면 된다.
자, 이제 본격적으로 *args란 무엇인지 살펴보겠다. *args는 "가변 인자"를 위한 변수다. 무슨 소린지 이해가 가는가? 필자도 처음에 이게 도대체 무슨 소리지 생각하고 있었다.
간단하게 설명하자면, 함수의 인자를 몇 개 받을지 모르는 경우에 사용한다.
예제 코드를 보며 설명해보겠다. 우리는 함수의 인자(파라미터)를 모두 더하는 함수를 하나 만들어볼 것이다.
def add():
pass
add(1, 2, 3, 4, 5)
이런 경우에는 1, 2, 3, 4, 5의 값을 모두 더한 후 더한 값을 리턴한다.
그런데, 여기서 문제가 하나 생긴다. 나중에 함수를 호출할 때, 인자가 몇 개가 들어올지 모른다는 것이다.
add(1, 2)
add(1, 4, 5)
add(1, 5, 10, 13, 19)
인자 2개를 보낼 수도 있고, 3개를 보낼 수도 있고, 5개를 보낼 수도 있다.
가변 인자는, 말 그대로 인자의 개수가 변할 수 있다는 뜻이다. 1개가 들어올 수도 있고, 100개가 들어올 수도 있다.
이제 가변 인자가 무엇인지 이해가 갔는가? 생각보다 어렵지 않은 개념이다.
그럼 *args가 가변 인자를 위한 변수인 건 알았는데, 어떻게 사용할까? 방법은 아주 간단하다. 그냥 인자에 *args를 추가하면 된다.
def add(*args):
pass
*args에 값을 집어넣으면 튜플 형태가 된다. add(1, 2, 3)이라는 함수를 호출하면, add라는 함수 안에 args라는 튜플이 생기고, 그 안에 튜플 형식인 (1, 2, 3)으로 담기게 된다.
def add(*args):
print(args)
add(1, 2, 3)
### 출력값 ###
(1, 2, 3)
첫 번째 인자에 접근하고 싶을 때는, args[0]으로 접근할 수 있다.
이제 *args의 사용법을 배웠으니, 아까 만들다 만 함수를 제대로 작성해보자.
def add(*args):
result = 0
for i in args:
result += i
print(result)
add(1, 10, 1302)
add(1, 2, 3, 19)
add(5)
### 출력값 ###
1313
25
5
args안에 저장돼있는 값을 result에 모두 더하는 함수다.
**kwargs는 무엇일까?
자, kwargs도 args와 마찬가지로 꼭 kwargs를 써줄 필요가 없다. kwargs 대신 helloworld라고 작성해도 무관하다. 하지만 앞에 *(별표) 2개를 꼭 붙여줘야 한다.
본격적으로 kwargs가 무엇인지 알아보기 앞서, 아까 args는 튜플 형태로 저장한다고 했다. kwargs는 args와 비슷하면서도 다르다. (참고로 kwargs는 keyword arguments의 약자다.)
kwargs는 딕셔너리 형태로 값을 저장한다. 또한 args와는 달리 파라미터 명을 같이 보낼 수 있다.
아래 예제 코드를 보며 설명해보겠다. 이번에는 이름과 나이를 저장하는 함수다.
def name_and_age(**kwargs):
print(kwargs)
name_and_age(name="홍길동", age="50")
### 출력값 ###
{'age': '50', 'name': '홍길동'}
name_and_age 함수 안에 kwargs라는 딕셔너리를 만들고, 그 안에 age와 name을 넣는다고 생각하면 된다.
*args와 **kwargs를 같이 쓴다면?
이제 *args와 **kwargs의 사용법을 알아봤다. 여기서 궁금한 점이 하나 생긴다. 둘이 같이 쓰면 어떻게 될까?
def number_and_name(*args, **kwargs):
print(args, kwargs)
number_and_name(1, 2, 3, name="홍길동")
### 출력값 ###
(1, 2, 3) {'name': 'GilDong Hong'}
함수에 키-값 형태로 된 인자를 주면 파이썬은 자동으로 kwargs에 저장해준다. 또한 아래 코드처럼 *args를 선언해놓고 사용하지 않을 수도 있다.
def name(*args, **kwargs):
print(args, kwargs)
name(name="GilDong Hong")
### 출력값 ###
() {'name': 'GilDong Hong'}
이런 경우에는 args에는 아무 값도 저장되지 않고, kwargs에만 키-값 형태로 저장되는 걸 볼 수 있다.
정리
*args와 **kwargs 모두 가변인자를 위한 변수다.
*args는 인자의 값이 튜플 형태로 저장된다.
**kwargs는 인자의 값이 딕셔너리 형태로 저장된다.
댓글