Python | 가변인자(*args)와 키워드 가변인자(**kwargs)

Sua·2020년 12월 25일
0

Python

목록 보기
16/28
post-thumbnail

가변인자와 키워드 가변인자를 이해하기 위해서는 먼저 패킹과 언패킹의 개념에 대해서 알아야 한다.

패킹(packing)

패킹은 여러 개의 데이터를 컬렉션으로 묶어 변수에 대입하는 것이다.

언패킹(unpacking)

언패킹은 컬렉션 속의 요소들을 여러 개의 변수에 나누어 대입하는 것이다.

numbers = (1, 2, 3, 4, 5)  # 패킹
a, b, c, d, e = numbers  # 언패킹

언패킹 시 변수의 갯수와 요소의 갯수가 일치해야 한다. 불필요한 값을 언더바를 사용하여 생략할 수도 있다.

a, _, _, d, e = numbers  # 필요 없는 요소를 _ 변수에 대입

남은 요소 대입받기

언패킹 시, 좌변의 변수 중 하나에 별 기호(*)를 붙이면, 남은 요소 전체를 리스트에 담아 대입한다.

>>> a, b, *rest = numbers     # 1, 2를 제외한 나머지를 rest에 대입
>>> print(a, b, rest)
1 2 [3, 4, 5]

>>> a, *rest, e = numbers     # 1, 5를 제외한 나머지를 rest에 대입
>>> print(rest)
[2, 3, 4]

위치 인자와 시퀀스 언패킹 사용하기

함수에 인자를 순서대로 넣는 방식은 위치 인자(positional argument)라고 한다. 일반적으로 사용하는 방식이다.

>>> print(10, 20, 30)
10 20 30

인수를 순서대로 넣을 때는 리스트나 튜플을 사용할 수도 있다. 다음과 같이 리스트 또는 튜플 앞에 별 기호*를 붙여서 함수에 넣어주면 된다. 별 기호를 붙이면 시퀀스를 풀어서 전달할 수 있으며(언패킹), 없으면 에러가 난다.
함수(리스트)
함수(
튜플)

>>> x = [10, 20, 30]
>>> print_numbers(*x)
10
20
30

가변인자(*args) 만들기

위치 인자와 시퀀스 언패킹의 개념은 가변 인자 함수를 만들 때 사용한다. 가변 인자를 사용하면 함수에 인수 한 개를 넣을 수도 있고, 열 개를 넣을 수도 있다. 또는, 인수를 넣지 않을 수도 있다.

가변 인자 함수는 매개변수 앞에 *를 붙여서 만든다. 변수의 이름은 자유롭게 지을 수 있지만 인자라는 의미의 args가 자주 사용된다.

def 함수이름(*매개변수):
    코드

숫자 여러 개를 받고, 숫자를 각 줄에 출력하는 함수를 만들어보자.

>>> def print_numbers(*args):
...     for arg in args:
...         print(arg)
...

숫자를 한 개 넣으면 한 개 출력되고, 네 개 넣으면 네 개가 출력된다.

>>> print_numbers(10)
10
>>> print_numbers(10, 20, 30, 40)
10
20
30
40

함수에 인자를 넣을 때, 리스트(튜플) 언패킹을 사용해도 된다.

>>> x = [10]
>>> print_numbers(*x)
10
>>> y = [10, 20, 30, 40]
>>> print_numbers(*y)
10
20
30
40

키워드 인자와 딕셔너리 언패킹 사용하기

매개변수에 이름으로 일치시키는 인자를 키워드 인자라고 한다. 함수를 호출할 때 인자의 값 뿐만 아니라 그 이름까지 명시적으로 지정해서 전달하는 방식이다. 인자의 순서와 용도를 매번 기억하지 않아도 되서 편리하다.

함수(키워드=값)

personal_info 함수를 키워드 인자 방식으로 호출하면 아래와 같다.

>>> def personal_info(name, age, address):
...     print('이름: ', name)
...     print('나이: ', age)
...     print('주소: ', address)
...

>>> personal_info(name='홍길동', age=30, address='서울시 용산구 이촌동')
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

단, 위치인자는 항상 키워드 인자보다 먼저 작성해야한다.

func('py', b='thon') # 가능
func(a='py', 'thon') # 불가능, SyntaxError

이번에는 딕셔너리를 사용해서 키워드 인수로 값을 넣는 딕셔너리 언패킹을 사용해보자. 다음과 같이 딕셔너리 앞에 **(별 기호 두 개)를 붙여서 함수에 넣어준다.

함수(**딕셔너리)

>>> x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**x)
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

**x처럼 딕셔너리를 언패킹하면 딕셔너리의 값들이 함수의 인자로 들어간다.

키워드 가변인자(**kwargs) 만들기

키워드 인자와 딕셔너리 언패킹의 개념은 키워드 가변 인자 함수를 만들 때 사용한다.

키원드 가변인자 함수는 매개변수 앞에 **를 붙여서 만든다. 변수의 이름은 자유롭게 지을 수 있지만 키워드 인자라는 의미의 kwargs가 자주 사용된다.

def 함수이름(**매개변수):
    코드

값 여러 개를 받아서 매개변수 이름과 값을 각 줄에 출력하는 함수를 만들어보자.

>>> def personal_info(**kwargs):
...     for kw, arg in kwargs.items():
...         print(kw, ': ', arg, sep='')
...

값을 한 개 넣어도 되고, 세 개 넣어도 됩니다.

>>> personal_info(name='홍길동')
name: 홍길동
>>> personal_info(name='홍길동', age=30, address='서울시 용산구 이촌동')
name: 홍길동
age: 30
address: 서울시 용산구 이촌동

인자를 넣을 때 딕셔너리 언패킹을 사용해도 된다.

>>> x = {'name': '홍길동'}
>>> personal_info(**x)
name: 홍길동
>>> y = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**y)
name: 홍길동
age: 30
address: 서울시 용산구 이촌동

보통 **kwargs를 사용한 가변 인수 함수는 다음과 같이 함수 안에서 특정 키가 있는지 확인한 뒤 해당 기능을 만든다.

def personal_info(**kwargs):
    if 'name' in kwargs:    # in으로 딕셔너리 안에 특정 키가 있는지 확인
        print('이름: ', kwargs['name'])
    if 'age' in kwargs:
        print('나이: ', kwargs['age'])
    if 'address' in kwargs:
        print('주소: ', kwargs['address'])

고정인자와 가변인자를 함께 사용하기

>>> def custom_print(*args, **kwargs):
...     print(*args, **kwargs)
...
>>> custom_print(1, 2, 3, sep=':', end='')
1:2:3

매개변수 순서에서 kwargs는 반드시 가장 뒤쪽에 와야 한다. 특히 고정 매개변수와 *args, kwargs를 함께 사용한다면 def custom_print(a, b, args, **kwargs):처럼 매개변수는 고정 매개변수, args, **kwargs 순으로 지정해야 한다.

본 포스팅은 아래의 사이트를 참고하여 작성되었습니다.
연오의 파이썬 https://python.bakyeono.net/chapter-6.html
코딩도장 https://dojang.io/
제대로 파이썬 https://wikidocs.net/22799
[Python] 가변인자, 패킹, 언패킹 https://chrisjune-13837.medium.com/python-%EA%B0%80%EB%B3%80%EC%9D%B8%EC%9E%90-%ED%8C%A8%ED%82%B9-%EC%96%B8%ED%8C%A8%ED%82%B9-a47ee2cdcac3
python - 패킹과 언패킹(packing & unpacking) https://nerd-mix.tistory.com/58

profile
Leave your comfort zone

0개의 댓글