카테고리 없음
[파이썬에서 살아남는법 제 21장] 변수 위치 인자를 사용해 시각적인 잡음을 줄여라
형혹성
2023. 3. 9. 14:50
※본 내용은 파이썬의 코딩 기술 (개정 2판)을 바탕으로 작성 했습니다.
위치 인자(positional arguments) 를 가변적으로 받을수 있으면 함수 호출이 더 깔끔해 진다.
이러한 인자를 가변인자, 스타 인자 라고 부르기도 한다.
예를 들어 디버깅 정보를 로그에 남기고 싶을때 아래와 같은 코드를 구성하였다.
def log(message, values):
if not values:
print(message)
else:
values_str = ', '.join(str(x) for x in values)
print(f'{message}: {values_str}')
log('내 숫자는', [1, 2])
log('하잉', [])
>>>
내 숫자는: 1, 2
하잉
근데 남길값이 없더라도 빈리스트를 만드는게 번거롭다
이럴경우 파이썬 마지막 위치 인자 이름 앞에 *을 붙이면 된다.
def log(message, *values): # 여기만 다름
if not values:
print(message)
else:
values_str = ', '.join(str(x) for x in values)
print(f'{message}: {values_str}')
log('내 숫자는', 1,2)
log('하잉')
>>>
내 숫자는: 1, 2
하잉
이미 시퀀스(리스트등) 이 있는데 Log 와 같은 가변 인자 함수에 시퀀스를 사용하고 싶다면 * 연산자를 사용하면 된다. *연산자는 파이썬이 시퀀스의 원소들을 함수의 위치인자로 넘길것을 명령한다.
favorites = [7, 33, 99]
log('Favorite colors', *favorites)
>>>
Favorite colors: 7, 33, 99
하지만 가변적인 연산자를 받는데 두가지 문제점이 있다.
1. 이런 선택적ㅇ니 위치 인자가 함수에 전달되기 전에 항상 튜플로 변환된다는것이다. 따라서 제너레이터의 모든 원소를 얻기 위해 반복하게 되고 이는 많은 연산량을 만들게 된다.
def my_generator():
for i in range(10):
yield i
def my_func(*args):
print(args)
it = my_generator()
my_func(*it)
>>>
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
2.함수에 새로운 위치 인자를 추가하면 해당 함수를 호출하는 모든 코드를 변경해야만 한다는 것이다. 이미 가변 인자가 존재하는 함수 인자 목록의 앞부분에 위치 인자를 추가하려고 시도하면, 기존호출의 코드가 깨질수도 있다.
def log(sequence, message, *values):
if not values:
print(f'{sequence} - {message}')
else:
values_str = ', '.join(str(x) for x in values)
print(f'{sequence} - {message}: {values_str}')
log(1, '최고 숫자', 7, 33) # New with *args OK
log(1, '하잉') # New message only OK
log('최고 숫자는', 7, 33) # Old usage breaks
>>>
1 - 최고 숫자: 7, 33
1 - 하잉
최고 숫자는 - 7: 33
예전 코드에서는 sequence 를 주지 않아서 7 을 message 파라미터로 사용했다. 아에 error 가 발생하지 않아서 디버깅을 하기 쉽지 않다.