*args, **kwargs에 대해서

우선 args와 *kwargs에 대해 알아보기 전에,
python에는 패킹언패킹이라는 것이 있다.

패킹 packing

  • 여러개의 데이터를 list, tuple 등의 컬렉션으로 감싸는 것 (묶는 것)
1
greetings = ['hello', 'konnichiwa', 'annyneong']

언패킹 (unpacking)

  • 컬렉션의 element들을 여러 변수에 푸는 것
1
en, jp, ko = greetings

여기까지는 쉽다.

이제 함수에서 사용할 때 살짝 헷갈린다.

1
2
3
4
5
6
7
def args_func(*args):
print(args)
print(type(args)) # <class 'tuple'>

args_func(1, 2, 3) # (1, 2, 3)
args_func((1, 2, 3)) # ((1, 2, 3),) # (1, 2, 3) 이 tuple의 element로 들어간다.
args_func([1, 2, 3]) # ([1, 2, 3],) # [1, 2, 3] 이 tuple의 element로 들어간다.

여기도 쉽다. 단순히 여러 파라미터를 tuple로 패킹하여 사용하는 것이기 때문이다.

1
2
3
4
5
6
def args_func(*args):
print(args)
print(type(args)) # <class 'tuple'>

my_tuple = (1, 2, 3)
args_func(*my_tuple) # (1, 2, 3)

나는 개인적으로 여기서 헷갈렸다.
args_func(my_tuple)가 아니고 *이 붙는지 이해를 잘 못했다.

그럼 이렇게 보면 어떨까

1
2
3
print((1, 2, 3)) # (1, 2, 3)
print(*(1, 2, 3)) # 1, 2, 3
print(1, 2, 3) # 1, 2, 3

2번째 줄과 3번째 줄은 서로 같은 결과를 출력한다.
이렇게 보면 *(1, 2, 3) 의 경우 (1, 2, 3)이라는 튜플이 언패킹된 결과라고 볼 수 있다.

그러므로 args_func(*args)의 경우는

1
2
3
4
my_tuple = (1, 2, 3)
1. args_func(*my_tuple)
2. args_func(*(1, 2, 3))
3. args_func(1, 2, 3)

이렇게 되는 것이고 볼 수 있을 것이다.

이를 확장시켜 생각해보면

1
2
3
4
5
6
7
8
def kwargs_func(**kwargs):
print(kwargs)
print(type(kwargs)) # <class 'dict'>

kwargs_func(en='hello', jp='konnichiwa', ko='annyneong')
kwargs_func(a=1, b=2, c=3)
my_dict = {'hello': 'world', '안녕': '세계'}
kwargs_func(**my_dict)

위 예제에서 kwargs_func(**my_dict)에서 **를 왜 사용했는지 이해가 될 것이다.

Share