지난번 포스팅에서는 함수의 매개변수 중에서 매개변수의 수가 함수 정의 시에 정한 개수로 고정되어 있는 위치 매개변수, 키워드 매개변수, 기본값 매개변수에 대해서 소개하였습니다. 


이번 포스팅에서는 매개변수의 수가 상황에 따라서 변화하는 가변 매개변수 (Arbitrary Arguments, Variable Length Arguments)에 대해서 알아보겠습니다. 


가변 매개변수는 

  - (1) *args_tuple : Positional 매개변수 (Tuple)

  - (2) **args_dict : 키워드 매개변수 (Dictionary)

의 두가지가 있습니다. 




함수 중에 보면 매개변수로 * (Asterisk), ** (Two Asterisks) 가 들어있는 경우 처음보는 분이라면 이게 무슨 뜻인가하고 궁금하였을 것입니다. 이번 포스팅을 보고 나면 이해가 될 것이예요. 



먼저 지난번 포스팅에서 소개했던 위치 매개변수를 복습해보겠습니다. line 2 에서 'print_list' 함수를 정의할 때 매개변수 'text_list' 1개만을 정의했으며, line 3에서 print_list() 함수를 호출할 때 mylist 1개를 매개변수 위치에 입력해주었더니 정상적으로 잘 출력을 해주었습니다. 



In [1]: mylist = ['Korea', 'Sweden', 'Mexico', 'Germany']


In [2]: def print_list(text_list):

    ...: for text in text_list:

    ...: print text


In [3]: print_list(mylist)

Korea

Sweden

Mexico

Germany

 



하지만, 아래의 line 4 에서 처럼 print_list() 함수의 매개변수에 ('Korea', 'Sweden', 'Mexico', 'Germany') 의 4개의 값을 입력하자 'TypeError: print_list() takes exactly 1 arguments(4 given)' 이라는 에러 메시지가 떴습니다. 이처럼 매개변수 값으로 여러개의 값을 이용하고자 할 때 쓰는 것이 가변 매개변수(arbitrary arguments, variable length arguments) 입니다. 



# TypeError: print_list() takes exactly 1 argument (4 given)

In [4]: print_list('Korea', 'Sweden', 'Mexico', 'Germany')

Traceback (most recent call last):


File "<ipython-input-4-5358764707f0>", line 1, in <module>

print_list('Korea', 'Sweden', 'Mexico', 'Germany')


TypeError: print_list() takes exactly 1 argument (4 given)

 


위의 line 4 처럼 했을 때 TypeError 가 났던 것을 Positional 가변 매개변수를 사용하여 정상적으로 작동하도록 고쳐보면 아래와 같습니다. 



  (1) *args_tuple : Positional 매개변수 (Tuple 형태)


괄호 안의 매개변수 입력란에 '* (Asterisk)' 로 시작하는 매개변수 이름을 넣어줍니다. 이 가변 매개변수는 Tuple 형태입니다. 



In [5]: def print_list_2(*text_list):

    ...: for text in text_list:

    ...: print text


In [6]: print_list_2('Korea', 'Sweden', 'Mexico', 'Germany') # more arguments

Korea

Sweden

Mexico

Germany

 



==============================================================


다음으로 사전형(Dictionary Type)을 매개변수 값으로 받아서 프린트를 해주는 함수를 정의해보겠습니다. 



In [7]: worldcup2018 = dict({'A': 'Russia, Saudi, Egypt, Uruguay',

   ...: 'F': 'Korea, Sweden, Mexico, Germany'})


In [8]: def print_group(group):

   ...: for i in group.keys():

   ...: print ("{0} : {1}".format(i, group[i]))


In [9]: print_group(worldcup2018)

A : Russia, Saudi, Egypt, Uruguay

F : Korea, Sweden, Mexico, Germany

 



위의 line 8 에서 정의한 함수에 아래의 line 10 처럼 여러 개의 사전형 값을 매개변수 값으로 입력하면 'TypeError: print_group() got an unexpected keyword argument 'A'' 라는 에러 메시지가 뜹니다. 



# TypeError: print_group() got an unexpected keyword argument 'A'

In [10]: print_group(A='Russia, Saudi, Egypt, Uruguay',

    ...: F='Korea, Sweden, Mexico, Germany')

Traceback (most recent call last):


File "<ipython-input-10-bae24f97b031>", line 2, in <module>

F='Korea, Sweden, Mexico, Germany')


TypeError: print_group() got an unexpected keyword argument 'A'

 



위의 line 10 처럼 매개변수 값으로 다수 개의 사전형 값을 사용하고 싶을 때 **agrs_dict 의 가변형 매개변수를 사용하면 됩니다. 


  (2) **agrs_dict : 키워드 매개변수 (Dictionary 형태)


사전형(Dictionary) 의 Key 값이 키워드 매개변수의 키워드(Keyword) 가 됩니다. 파이썬 라이브러리의 함수들을 보다 보면 **kwagrs 라고 표현된 경우가 있는데요, 이때 kw 가 KeyWord 의 K(ey)W(ord) 의 kw 를 따온 거예요. 



In [11]: def print_group_2(**group):

    ...: for i in group.keys():

    ...: print ("{0} : {1}".format(i, group[i]))


In [12]: print_group_2(A='Russia, Saudi, Egypt, Uruguay',

    ...: F='Korea, Sweden, Mexico, Germany')

A : Russia, Saudi, Egypt, Uruguay

F : Korea, Sweden, Mexico, Germany

 




  (3) 순서 : *args_tuple 먼저, **args_dict 나중에


*args_tuple 과 **args_dict 두 가지 유형의 가변 매개변수를 모두 사용하여 함수를 정의할 수 있습니다. 단, 이때 순서가 중요합니다. *args_tuple 을 먼저 정의하고, **args_dict 를 나중에 이어서 정의해야 합니다. 



#%% arguments sequence matters

In [13]: def print_all(*tup, **dic):

    ...: print(tup)

    ...: print(dic)


In [14]: print_all(1, 2, 3,

    ...: A='Russia, Saudi',

    ...: F='Korea, Sweden')

(1, 2, 3)

{'A': 'Russia, Saudi', 'F': 'Korea, Sweden'}

 



만약 아래의 line 15 처럼 **args_dict 먼저 정의하고, *args_tuple 을 그 뒤에 이어서 정의하게 되면 'SyntaxError: invalid syntax' 라는 에러 메시지가 뜹니다. 



# SyntaxError: invalid syntax

In [15]: def print_all(**dic, *tup):

    ...: print(tup)

    ...: print(dic)

    ...:

    ...:

File "<ipython-input-15-3e33a9bb0436>", line 1

def print_all(**dic, *tup):

^

SyntaxError: invalid syntax

 



많은 도움이 되었기를 바랍니다. 


Posted by R Friend R_Friend