print함수는 출력하고자하는 객체가 몇개던지, 즉 몇개의 인자를 받던지 상관하지 않고 출력해줍니다. 이런 경우처럼 함수가 받을 인자의 갯수를 유연하게 지정할 수 있다면 보다 유연하게 코드를 작성할 수 있습니다.
파이썬은 이런 경우를 지원하기 위해 packing을 지원합니다.
패킹은 인자로 받은 여러개의 값을 하나의 객체로 합쳐서 받을 수 있도록 합니다.
위치인자 패킹은 *한개를 매개변수 앞에 붙임으로 사용합니다.
def func(*args):
print(args)
print(type(args))
func(1, 2, 3, 4, 5, 6, 'a', 'b')
-result-
(1, 2, 3, 4, 5, 6, 'a', 'b')
<class 'tuple'>
이런식으로 매개변수 이름 앞에 *을 붙여준다면, 위치인자로 보낸 모든 객체들을 하나의 객체로 관리해줍니다.
이러한 packing을 통해 받은 모든 숫자들의 합을 구하는 연산도 구할 수 있습니다. 몇개든 상관없이 가능합니다.
def sum_all(*numbers):
result = 0
for number in numbers:
result += number
return result
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5, 6)) # 21
-result-
6
21
packing을 이용해서 반드시 받아야하는 매개변수와 여러개를 받을수있는 매개변수를 구분해서 작성할 수 있습니다.
def print_family_name(father, mother, *sibling):
print("아버지 :", father)
print("어머니 :", mother)
if sibling:
print("호적 메이트..")
for name in sibling:
print(name)
print_family_name("홍길동", '심사임당', '김태희', '윤아')
-result-
아버지 : 홍길동
어머니 : 심사임당
호적 메이트..
김태희
윤아
위치인자가 패킹하는 매개변수를 만나면 그 이후에 위치인자가 몇개이던지, tuple로 하나의 객체가되어서 관리됩니다.
def kwpacking(**kwargs):
print(kwargs)
print(type(kwargs)
kwpacking(a=1, b=2, c=3)
-result-
{'a': 1, 'b': 2, 'c': 3}
<class 'dict'>
키워드 인자는 패킹한 인자들을 키워드와 인자 쌍으로 이뤄진 딕셔너리로 관리합니다.
이를 이용해서 print_family_name함수에 호적메이트들에 사회적명칭도 출력하도록 변경할 수 있습니다.
def print_family_name(father, mother, **sibling):
print("아버지 :", father)
print("어머니 :", mother)
if sibling:
print("호적 메이트..")
for title, name in sibling.items():
print('{} : {}'.format(title, name))
print_family_name("홍길동", '심사임당', 누나='김태희', 여동생='윤아')
-result-
아버지 : 홍길동
어머니 : 심사임당
호적 메이트..
누나 : 김태희
여동생 : 윤아
위치 인자와 키워드 인자 packing을 동시에 사용할 수 있습니다.
def print_family_name(*parents, **sibling):
print("아버지 :", parents[0])
print("어머니 :", parents[1])
if sibling:
print("호적 메이트..")
for title, name in sibling.items():
print('{} : {}'.format(title, name))
print_family_name("홍길동", '심사임당', 누나='김태희', 여동생='윤아')
packing과 반대되는 개념인 unpacking이라는 개념이 있습니다.
packing은 여러개의 객체를 하나의 객체로 합쳐주었습니다. unpacking은 여러개의 객체를 포함하고 있는 하나의 객체를 풀어줍니다.
함수에서 unpacking을 할때는, 매개변수에서 을 붙이는게 아니라 인자 앞에 을 붙여서 사용합니다.
def sum(a, b, c):
return a + b + c
numbers = [1, 2, 3]
print(sum(*numbers))
-result-
6
[1, 2, 3]을 인자로 보낼때, *을 붙이면 unpacking이 발생합니다.
unpacking은 아래와 같은 순서로 변경되어 실행됩니다.
sum(*[1, 2, 3, 4])
결과
TypeError: sum() takes 3 positional arguments but 4 were given
위치인자를 unpacking할때는 위에 예에서는 list타입이였지만, Container객체라면 다 가능합니다.
sum(*'abc') # 'abc'
sum(*(4, 5, 6)) # 15
sum(*{'가', '나', '다'}) # '나다가'
sum(*{'치킨': 3, '피자': 12, '음료수': 10}) # '치킨피자음료수'
set타입과 dict타입은 순서정보를 가지고 있지 않기 때문에 결과가 다를 수 있습니다.
동일한 방식으로 키워드인자로 unpacking할 수 있습니다. unpacking하기 위해선 인자가 key와 인자로 구성되어 있는 mapping타입, 즉 dict가 필요합니다.
def cal(first, op, second):
if op == '+':
return first + second
if op == '/':
return first / second
if op == '-':
return first - second
if op == '*':
return first * second
prob = {
'first': 12,
'second': 34,
'op': '*'
}
cal(**prob)
-result-
408