이 포스트는 키워드 아규먼트와 포지셔널 아규먼트를 알고 있다고 전제하고 작성되었습니다.
파이썬 함수 정의를 보다보면 아래처럼 되어있는 경우가 많다.
def foo(*args, **kwargs):
...
그냥 파라미터랑 뭔가 다르다. 앞에 왜 *
, **
이 달려있고, 파라미터는 아무 이름이나 정해도 되는데 왜 다들 무슨 뜻이길래 저렇게 args
랑 kwargs
라고 쓰는가? 그리고 왜 항상 순서는 *args
다음에 **kwargs
인가?
내가 인풋 정수들을 모두 더해주는 함수를 만들고 싶다고 하자.
def sum_ints(a,b,c):
return a + b + c
위 함수는 세 개의 수를 받아서 그 합을 계산해줄 것이다. 근데 내가 만약에 n개의 인자를 받고 싶다면 어떻게 할 것인가? 1개든 3개든 10개든 정수를 받아서 그 합을 구하고 싶다면 저렇게 함수를 정의해서는 안될 것이다. 이렇게 몇 개의 positional argument(인자를 이름으로 받지 않고 ',' 로 구분하여 위치로 받는 인자) 를 받아야할지 정할 수 없을 때 그 여러 개를 받을 자리에 *args
를 파라미터로 써준다. (꼭 args 라고 쓸 필요는 없으나 관습적으로 그렇게 쓴다.)
def sum_n_ints(*args):
return sum(args)
args 앞에 붙는 *
가 여러 개의 인자를 묶어서 하나의 튜플로 묶어주고 이를 args 에 할당한다라고 생각하면 되겠다.
그렇다면 이번에는 알 수 없는 숫자만큼의 키워드 아규먼트들을 받고 싶다고 하자. 이때도 일반적인 키워드 파라미터를 정하는 방식으로는 함수를 정의할 수 없다. 그래서 여러 개의 키워드 아큐먼트들을 묶어서 딕셔너리로 만들어주는 **
이 필요하다.
*args
는 연속되는 포지셔널 아규먼트를 다 먹는다.**kwargs
는 연속되는 키워드 아규먼트를 다 먹는다.*args
와 **kwargs
순서를 맞춰서(**kwargs
를 먼저 쓰면 안된다!) 쓰면 키워드 아규먼트가 나오기 전까지는 args 가 튜플로 먹고, 뒤 이어오는 키워드 아규먼트는 kwargs 가 딕셔너리로 먹는다.*args
, **kwargs
순서를 바꿔쓰면 syntax error 가 난다.*args
는 연속되는 포지셔널 아규먼트를 다 먹는다고 했다. 따라서 위처럼 *args1
가 다 먹을 것이므로 *args2
는 있을 수 없다.**kwargs
도 마찬가지다.
이렇게 넣는 것은 **kwargs
가 뒤로 연속되는 키워드 아규먼트를 다 먹을 것이므로 안된다.
이렇게 해주면 *args
는 이어지는 포지셔널 아규먼트만 먹기에 a=1
전에서 끊길 것이고, **kwargs
는 b=2
뒤로 이어지는 키워드 아규먼트들을 먹을 것이니 문제 없다!
오! 이해가 금방 됩니다!!