가변 인수는 일반적으로 args(argumens)로 많이 쓰인다(arg가 아닌 다른 이름으로 사용해도 사용 가능하다). 변수 앞에 애스터리스크(*) 를 붙여서 사용하며, 이렇게 애스터리스크를 사용하여 변수를 넘겨주면 함수 내부에서는 가변인자를 튜플로 인식하게 된다.
def print_args(*args):
print(type(args))
print_args()
<class 'tuple'>
타입이 튜플이니 for문 같은 이터레이터에서 사용할 수 있는 여러 기능 및 튜플의 여러 기능을 사용할 수 있으며, 아래의 코드처럼 명시적으로 튜플을 넘겨 줄 수 있다.
a = (1, 2, 3, 4, 5)
b = (10, 11, 12, 13, 14, 15, 16, 17)
def print_args(*args):
for arg in args:
print(arg)
print_args(*a)
print_args(*b)
1
2
...
4
5
10
...
16
17
위의 코드처럼 사실 저런식으로 사용하지는 않는다 가변 인수는 인수의 수가 정해져 있지 않은 상황에서 쓰인다. 예를 들어 아래와 같이 인수의 갯수가 달라도 오류를 띄우지 않는다.
def print_args(*args):
for arg in args:
print(arg)
print_args(1, 2, 3, 4, 5)
print_args(10, 11, 12, 13, 14, 15, 16, 17)
1
2
...
4
5
10
...
16
17
가변 인수와 고정인수를 같이 사용할때에는 고정 매개변수를 먼저 기입한 뒤, 가장 마지막에 가변 매개변수를 기입해야 한다.
def print_args(*args, a):
print(type(args), type(a))
print_args(1, 2, 3, 'test')
Traceback (most recent call last):
File "C:Python_Workspace/DeepMom/main.py", line 5, in <module>
print_args(1, 2, 3, 'test')
TypeError: print_args() missing 1 required keyword-only argument: 'a'
가변인수튜플이 함수 매개변수로 넘어가면 언패킹이 되어 test
라는 문자열 변수를 *args
가 가지고있던 값중 하나로 취급되기 때문에 a
를 argument의 값을 찾지 못했다고 나온다.
kwargs는 keyword arguments의 약어로 args와 마찬가지로 반드시 이름이 karg로 정해져 있는것은 아니다. *arg
와는 다르게 애스터리스크가 두번 붙으며 함수의 매개변수로 넘어가면 딕셔너리로 인식하게 된다.
def print_kargs(**kwargs):
print(type(kwargs))
print_kargs()
<class 'dict'>
가변인수처럼 명시적으로 딕셔너리를 대입 할 수도 있다.
test_dict = {'Korea': 'seoul', 'USA': 'washington dc', 'Japan': 'Tokyo'}
def print_kwargs(**kwargs):
print(kwargs.keys())
print(kwargs.values())
print_kwargs(**test_dict)
dict_keys(['Korea', 'USA', 'Japan'])
dict_values(['seoul', 'washington dc', 'Tokyo'])
하지만 키워드 가변인수역시 키워드 인수의 확장을 위해서 사용된다. 키워드 가변인수를 이용하면 다음과 같은 코드를 쓸 수 있다.
def print_kwargs(**kwargs):
print(kwargs.keys())
print(kwargs.values())
print_kwargs(korea='seoul', USA='washington dc')
dict_keys(['korea', 'USA'])
dict_values(['seoul', 'washington dc'])
다음과 같은 코드를 살펴보자.
test_dict = {'Korea': 'seoul', 'USA': 'washington dc', 'Japan': 'Tokyo'}
def print_kwargs(**kwargs):
print(*kwargs) # 애스터리스크를 하나만 붙여보자!
print(kwargs)
print_kwargs(korea='seoul', USA='washington dc')
korea USA
{'korea': 'seoul', 'USA': 'washington dc'}
위 코드처럼 함수 내부에 키워드 가변인수에다 애스터리스크를 하나 붙여서 호출하면 딕셔너리의 키 들이 나타남을 확인 할 수 있다.
가변인수와 키워드 가변인수는 다음과 같은 순서로 지정해야 사용할 수 있다.
def func(a, *args, **kwargs):
만약 위와같은 순서를 지키지 않는다면, Pycharm 같은 IDE를 사용한다면 아래와 같은 경고가 나오며, 실행 시켜도 SyntaxError: invalid syntax
가 발생하기 때문에 실행 자체가 되지 않는다.
- Regular Positional Arguments
- Default Arguments
- Variable length positional arguments
- Non-Default Keyword-only arguments & Keyword-only arguments WithDefaults
- Variable Length Keyword Arguments
인수의 순서를 위와같이 지켜주지 않으면 에러가 난다. 예시를 들어 다음과 같은 코드를 확인 해 보자
def func(a, *args, b, **kwargs, c, d='default', e='default'):
print('a =', a)
print('b =', b)
print('c =', c)
print('d =', d)
print('e =', e)
print('a rgs=', args)
print('kwargs =', kwargs)
func('a', 'c', 'f', 'g', b='b', e='e', h='h')
파라미터의 위치가 지켜지지 않았으므로 오류가 난다. def func()
의 에서 서술한 순서로 본다면 각 인자는
a
= Regular positional argumentsb
= Non-Default Keyword-only arguments*args
= Regular positional argumentsc
= Regular Positional Arguments**kwargs
= Variable Length Keyword Arguments d
= Default Argumentse
= Keyword-only arguments WithDefaults이므로 아래와 같이 순서를 맞춰주면 코드실행이 가능하다.
def func(a, c, d='default', *args, b, e ='default', **kwargs,):
print('a =', a)
print('b =', b)
print('c =', c)
print('d =', d)
print('e =', e)
print('a rgs=', args)
print('kwargs =', kwargs)
func('a', 'c', 'f', 'g', b='b', e='e', h='h')