○ 함수에 데이터를 전달한다
아래 그림은 지난번 글인 [함수에 대한 이해 - Part 1]에서 같이 봤던 그림이다. 빨간색 글자로 추가한 부분에 주목해 주시기 바란다. 함수의 전부이기도 한 arguments와 return values 이다. 이번 글에서는 arguments(인자)에 대해서 살펴보고 다음 글에서 return values(반환값)에 대해 살펴보도록 한다.
파이썬에서는 함수에 인자를 전달하는 방법으로 2가지 방식을 제공한다. 위치인자(positional argument)와 키워드 인자( keyword argument) 방식이 그것이고, 이들과 함께 default argument (디폴트 인자) 가 함께 사용된다.
○ 위치 인자(positional arguments)
함수에 데이터를 전달하는 가장 기본적인 방법이다. 함수 호출을 통해 전달되는 인자들은 함수의 매개변수 리스트에 정의된 변수의 순서대로 값이 할당된다. 예를 들어 보자.
어떤 함수의 signature가 f (a, b, c) 라는 것은, 이 함수의 실행을 위해서는 3개의 인자를 전달해야 한다는 뜻이다. 참고로, 아래의 코드에서 사용된 pass 라는 명령어는 null operation 으로서, 문법적으로 어떤 코드가 필요하지만 실제 들어갈 코드가 없는 경우에 사용된다. Pass 명령어는 실행되어도 아무 일이 생기지 않는다.
위의 f( ) 함수를 호출하기 위해서는 3개의 값이 인자로 전달되어야 한다. 이것은 함수의 signature 에서 정의된 바와 같다. 실제로 In[14]에서와 같이 f(1, 2, 3) 이라고 호출이 되면 각 인자의 순서에 맞게 매개변수로의 할당이 이루어진다. 그래서, 첫번째 1 값은 첫번째 매개변수 a 로, 두번째 인자인 2 값은 두번째 매개변수인 b 로, 세번째 인자인 3 값은 세번째 매개변수인 c 로 할당된다. 즉, f(1, 2, 3)으로 함수 호출이 이루어질 때, f( ) 함수 내부에서 a 값은 1이 되고 (a=1), b 값은 2가 되고 (b=2), c 값은 3이 된다. 실제 함수의 body는 pass 되어 아무런 일도 벌어지지 않음은 참고하기 바란다.
그런데 In[15]와 같이 매개변수가 3개인 함수 f ( )를 2개의 인자만을 전달하면서 호출하고자 하면 f( ) missing 1 required positional argument : 'c' 라는 에러가 발생하게 된다. f( ) 함수의 호출에 'c' 이름에 해당하는 위치인자가 빠져있다는 에러이다.
즉, 매개변수의 개수 만큼의 인자가 함수에서 정의된 매개변수의 순서에 맞게 전달되는 방식을 위치 인자 (positional argument) 라고 부른다. 아래 그림을 참고하기 바란다.
그런데 모든 값이 인자로서 반드시 전달될 것이 요구되지는 않는다. 어떤 값들은 디폴트 (default) 값이 미리 정해져 있다. 즉, 특별히 다른 할당이 이루어지지 않는다면 사전에 정의된 값 (디폴트 값) 이 할당된다. 매개변수(들)의 디폴트 값이 정해져 있는 경우에, 함수의 매개변수는 아래와 같은 형태로 정의된다. 아래 함수의 정의(In[36]) 에서 밑줄친 부분은, 3개의 매개변수 중 c 값은 반드시 요구되는 값은 아니며, 만약 따로 값이 전달되지 않으면 디폴트로 100 값이 할당된다는 것을 나타낸다. In[37]과 In[38]은 함수의 호출의 사용예를 보이고 있다.
In[37]의 경우에는 매개변수의 개수와 같은 3개의 값이 인자로 나타나 있다. 이 경우에는 디폴트 값이 무시되고 세번째 인자로 전달된 1000 값이 c 변수에 저장되게 된다. 실제 출력 값에 1000 이 출력됨을 확인하기 바란다.
In[36]에서 정의된 f( ) 함수의 매개변수를 리스트를 보면, 3개의 매개변수 중 2개 a 와 b 는 필수적으로 요구되는 인자이나 마지막 c 매개변수는 선택적임을 나타내고 있다. In[38]의 함수 호출은 반드시 필요한 2개의 인자들 만을 전달하고, 디폴트 값이 정의된 인자인 c 는 디폴트 값을 사용하겠다는 의도를 나타내고 있다. 실제로 출력된 결과를 보면 디폴트 값인 100이 c 변수에 저장되었음을 확인할 수 있다.
디폴트 인자를 사용할 때 한가지 주의사항이 있는데, 디폴트 인자(default argument) 뒤에 디폴트 값이 없는 매개변수(non-default argument) 를 정의할 수 없다는 것이다. 실제로 이 규칙을 어기고 함수를 정의하게 되면, 아래 그림에서 보는 바와 같이 non-default argument follows default argument 라는 에러가 발생하게 된다. 만약 In[39]와 같은 함수 정의를 허용한다면, 함수호출에 일의적으로 해석할 수가 없는 모호한 경우가 발생한다. 예를 들어, f(10, 20) 이면 a 값은 10, b 값은 디폴트, c 값은 20 인 정당한 함수호출로 볼 것인지, 아니면 a 값은 10, b 값은 디폴트 값인 100 대신에 20, 그런데 c 값이 빠졌으므로 잘못된 함수호출로 볼 것인지 애매해지기 때문이다.
물론, 디폴트 인자를 2개 이상 선언하는 것도 가능하다. 단, default 인자 뒤에 Non-default 인자가 위치하면 안된다 (아래 코드 참조)
파이썬 내장함수인 print 함수의 설명을 보면, sep, end, file, flush 등의 4개 매개변수에 디폴트 값이 선언되어 있음을 확인 할 수 있다. 이 부분을 조정함으로써 print( ) 함수의 작동을 조정할 수 있는데 이에 대해서는 아래 키워드 인자 부분을 공부한 다음에 살펴보기로 하겠다.
○ Keyword argument (키워드 인자)
위에서 positional argument 들은 인자가 정의된 순서에 따라 값이 할당된다고 했었는데, 키워드 인자를 사용하게 되면 그 순서를 지키지 않아도 된다. 키워드 인자는 함수 호출에서 "매개변수=값" 형태로 순서에 무관하게 값을 할당할 수 있는 방식이다. 아래 코드 중 In[58]은 키워드 인자 전달 방식으로 f( ) 함수를 호출하는 예를 보이고 있다.
키워드 인자 방식은, 함수의 매개변수들의 이름을 알고 있으면, 매개변수의 순서에 상관없이 인자를 전달할 수 있는 장점이 있다. 하지만, 이런 일반적인 경우 보다는 여러개의 디폴트 인자 중 1~2개의 인자 값을 바꾸고자 할 때, 매우 효과적으로 활용할 수 있다. 아래의 print( ) 함수의 경우로 살펴보자.
Print( ) 함수 중에 sep 이란 변수는 여러 값을 출력할 때 그 값들 사이에 끼어지는 문자열이다. 디폴트 값으로 공백문자(space)가 사용되고 있다. 아래의 예는 sep 매개변수의 디폴트 값을 키워드 인자 전달 방식을 이용해 바꾸는 것을 보여 주고 있다. 키워드 인자 방식은, 이와 같이, 여러개의 디폴트 인자 중에 특별히 몇 개 변수의 값을 조정하고자 할 때, 효과적으로 사용할 수 있다.
○ 매개변수의 개수가 변한다 : *args, **kwargs
함수를 정의하다 보면, 함수의 성격에 따라, 매개 변수의 개수가 고정되는 경우도 있지만 가변적인 경우도 있다. 우리가 흔히 사용하다시피 print( ) 함수의 경우에는 인자의 수가 고정되어 있지 않다. 너무 당연하게 사용하고 있지만, 확인 차원에서 보이면 아래의 코드와 같다. Print( ) 함수에 1개의 인자도 전달할 수 있고, 2개의 인자를 전달할 수도 있다. 사실 전달할 수 있는 인자의 개수에 제한이 없다. 이러한 경우에 매개 변수를 어떻게 정의할 수 있는지에 대해 살펴보기로 하자. 참고로, In[70]에서와 같이, 하나의 명령문에서 여러개의 변수 할당을 정의할 수 있다. 가끔은 유용하게 사용할 수 있는 문법이니, 눈에 익혀두면 좋겠다.
매개변수의 개수가 변동적일 때에는 우리가 알고 있는 위치인자나 키워드 인자를 활용할 수가 없다. 이러한 경우를 위해 파이썬은 *args, **kwargs 문법을 제공하고 있다. 매개변수에 별표(*) 없이 사용된 변수는, 예를 들어 a 와 같이, 1개의 매개변수를 의미한다. 별표(*) 1개와 함께 사용된 경우는, 예를 들어 *a 와 같이, 1개의 튜플을 나타낸다. 별표 2개(**)와 함께 사용된 매개변수는, 예를 들어 **a 와 같이, 1개의 딕셔너리 개체를 표현한다.
예를 들어 어떤 함수의 선언이 f(a, *b, **c) 라고 한다면, 전달된 첫번째 인자는 a 값으로, 키워드로 전달된 인자들은 c 값으로, 일반 매개 변수부터 키워드 인자 사이에 입력된 인자들은 튜플로 전달된다. 아래의 코드에서 전달되는 데이터의 타입을 확인해 보았다.
위의 예제에서 인자들과 매개변수 간의 매칭을 살펴보면 아래의 그림과 같이 나타낼 수 있겠다.
실제 f( ) 함수의 바디에서 인자로 넘어온 값들에 직접 접근하여 출력해 보면 아래와 같다.
이해를 돕기 위해, 이 방식을 사용하여, 여러개의 인자를 받아서 그 값들의 합을 구하는 함수를 구해 보자. 함수의 이름은 sum으로 하고, 여러개의 정수 값이 인자로 들어오면 그 데이터들을 tuple로 받아 처리하였다. 아래의 코드를 참고하기 바란다.
'파이썬 (python)' 카테고리의 다른 글
[python 18] 매직 명령어와 파일관리 (1) | 2020.03.30 |
---|---|
[python 17] 함수 - Part 3 : return (0) | 2020.03.25 |
[python 15] 함수 - Part 1 : 개요 (0) | 2020.03.25 |
[python 14] 파이썬 문자열 String (0) | 2020.03.25 |
[python 13] 데이터 구조 - 튜플, 딕셔너리 (1) | 2020.03.16 |