BATTER WAY 18. 가변 위치 인수로 깔끔하게 보이게 하자
- 파이썬으로 코딩하다가, 가변적으로 인수를 받을 때가 있다.
- 이러한 경우에 사용하면 좋을 것 같다.
예제
def log(message, values):
if not values:
print(message)
else:
values_str = ', '.join(str(x) for x in values)
print('%s : %s' % (message, values_str))
log('My number are', [1, 2])
log('Hi there', [])
-
위의 코드에서는 로그로 남길 값이 없을 때, 빈 리스트로 넘겨주고 있다.
-
파이썬에서는
*
기호를 마지막 위치의 파라미터 이름 앞에 붙이면, 된다. -
맨 앞에 나오는 인수는 필수적이지만,
*
가 붙은 인수는 가변적이다. -
함수 본문은 수정할 필요가 없고, 단지 호출하는 쪽만 수정하면 된다.
def log(message, *values):
if not values:
print(message)
else:
values_str = ', '.join(str(x) for x in values)
print('%s : %s' % (message, values_str))
log('My number are', [1, 2])
log('Hi there')
- 인자가 필요하지 않을 때에는, 사용하지 않아도 된다.
가변 개수의 인수를 받는 방법의 문제점
1. 가변 인수가 함수에 전달되기에 앞서, 항상 튜플로 변환된다는 점이다.
-> 함수를 호출하는 쪽에서 제네레이터를 사용하면, 결과로 만들어 지는 튜플의 개수가 많은 경우, 메모리를 많이 차지하여 프로그램이 죽을 수 있다.
2. 추후에 호출 코드를 변경하지 않고서는 새로운 위치에 인수를 추가할 수 없다는 점이다.
-> 새로운 위치에 인수를 추가할 경우, 호출하는 코드를 변경해줘야한다. 그렇지 않으면 버그가 발생한다.
핵심 정리
-
def
문에서*args
를 사용하면, 함수에서 가변 개수의 위치 인수를 받을 수 있다. -
*
연산자를 사용하면, 시퀀스에 들어 있는 아이템을 함수의 위치 인수로 사용할 수 있다. -
제네레이터와
*
연산자를 함께 사용하면, 프로그램이 메모리 부족으로 망가질 수 있다. -
*args
를 받는 함수에 새 위치 파라미터를 추가하면 정말 찾기 어려운 버그가 생길 수 도 있다.