2011년 3월 30일 수요일

[Python] Arguments of Function

Python 에서 함수를 다수의 인자(argument)로 호출해야 할 때 사용할 수 있는 여러가지 방법 메모.

(여기서는 '인자'라는 용어에 주의해야 하는데, 호출하는 입장에서는 parameter, 호출 받는 입장에서는 argument로 표현한다. 한글로는 '인자'라는 말 말고 뭘 써야 할지 난감하다. 뭐 딱히 신경 안써도 되는 이야기 이긴 하다 -_-;;;)

Named Parameter


인자의 이름, 즉 함수 입장에서는 변수 이름을 호출하는 쪽에서 지정해서 쓰는 방법. 이름을 지정하게 되면 순서에 구애받지 않게 인자(parameter)를 넘겨줄 수 있고 또한 가독성 면에서 더 나은 편이다.

>>> def funca(a=1, b=2, c=3):
...     print a, b, c
... 
>>> funca(1, 2, 3)
1 2 3
>>> funca(1, b=2)
1 2 3
>>> funca(10, c=10)
10 2 10
>>> funca(a=10, 2, 5)
  File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg

위 처럼 넘기는 패러미터 이름을 호출할 때 지정할 수도 있다. 기본 중의 기본. 하지만 마지막 예 처럼 첫 패러미터에 이름을 지정한 후 이후 인자(parameter)에는 이름을 지정하지 않으면 오류가 발생한다.

list / tuple / dict


인자(argument)가 너무 많은 함수를 호출한다면 가독성 면에서 굉장히 괴로울 수도 있다. 이럴 때는 인자를 따로 쓰지 말고 list나 tuple, 혹은 dict(Dictionary)를 사용하는 것도 좋은 방법이다.

def funcb(a, b):
...     print a
...     for bb in b: print bb
... 
>>> funcb(1, (1, 2))
1
1
2
>>> funcb(1, [3, 4])
1
3
4
>>> funcb(5, {'a':10, 'b':5})
5
a
b

이 중 리스트나 튜플 형태를 사용했을 때는 순서나 갯수가 어긋나면 안되기에 철저하게 처리하도록 해야 한다.

이런 방식을 이용할 때는 가급적 dict를 이용하는게 명확하다. 예제에서는 그저 하나하나씩 찍게 해 놨지만, 실제로 사용할 때는 해당 인자에서 키워드를 이용해 값을 얻어오는 방식으로 사용하면 가독성도 좋아진다.

가변 인자(갯수를 마음대로 지정 가능한 방식)


보통 C에서 대표적인 예로 printf 등을 들 수 있다. 인자(parameter)의 갯수가 format에 따라 변한다. C에서는 va_args나 va_list 등의 키워드를 쓰는 방식으로 구현하는 그런 류다. Python에서는 이를 아주 간단한 방법으로 2가지 형태로 구현할 수 있다.

def funcc(*args):
...   for a in args: print a
... 
>>> funcc(1, 2, 3)
1
2
3

*args 라고 표현한 인자(argument)가 첫 번째 예. 이름은 마음대로 지어도 되지만 앞에 별표가 붙어있다. 함수를 이런 식으로 정의하게 되면 인자를 리스트 형태로 넘겨받을 수 있게 된다.

하지만 이 방식은 Named Parameter, 즉 인자에 이름을 붙여서 사용할 수가 없다.

다른 방법은 사전(dict) 형태이다.

def funcd(**kwargs):
...   for key in kwargs:
...     print key, '=', kwargs[key]
... 
>>> funcd(a=1, b=2, c=3)
a = 1
c = 3
b = 2
>>> funcd(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: funcd() takes exactly 0 arguments (3 given)

이번에는 별표가 두개 붙어 있는 형태다. 이 경우 모든 인자(argument)는 dict 형태로 넘어가서 해당 인자의 이름을 키로 넘겨진 데이터를 읽을 수 있다.

하지만 리스트 형태와는 달리, 이 경우에는 호출할 때 반드시 모든 인자(parameter)에 이름을 넘겨줘야 한다. 없다면 마지막 예 처럼 에러가 발생하게 된다. 사전 형이기 때문에 당연히 키가 필요하기 때문이다.

이 외에 다른 좋은 방법이 있을 지도 모르겠지만 일단 여기까지만 정리.

댓글 없음 :