파이썬에서 임의의 개수의 인자를 받는 가변인수 가 존재한다.
*args (variable length arguments) :
전달 받은 임의의 개수 인자를 Tuple 형태로 저장한다.(...,"...",...)
def func_param_with_var_args(name, *args, age):
print("name=",end=""), print(name)
print("args=",end=""), print(args)
print("age=",end=""), print(age)
func_param_with_var_args("정우성", "01012341234", "seoul", 20)
--> TypeError: func_param_with_var_args() missing 1 required keyword-only argument: 'age'
예시에서 처럼 가변인수를 사용하게 되면 age 라는 parameter 값을 전달받지 못했다고 오류가 뜬다.
간단하게 생각하면 쉽다. 임의의 개수를 전달받기 때문에 가변인수가 뒤에 오는 parameter 가 값을 전달 받지 못한 것이다. 호출 시 마지막 argument 를 positional argument 에서 keyword argument 로 변경해주면 정상 작동한다!
def func_param_with_var_args(name, *args, age):
print("name=",end=""), print(name)
print("args=",end=""), print(args)
print("age=",end=""), print(age)
func_param_with_var_args("정우성", "01012341234", "seoul", age=20)
-->
name=정우성
args=('01012341234', 'seoul')
age=20
임의의 개수의 키워드 인자를 받는 가변 키워드 인자 도 있다.
**kwargs(variable length keyword arguments) :
전달받은 키워드 인자를 Dictionary 형태로 저장한다.{... : ... , ... : "..." }
def func_param_with_kwargs(name, age, **kwargs, address=0):
print("name=",end=""), print(name)
print("age=",end=""), print(age)
print("kwargs=",end=""), print(kwargs)
print("address=",end=""), print(address)
func_param_with_kwargs("정우성", "20", mobile="01012341234", address="seoul")
--> invalid syntax
이번엔 구문에러가 발생했다. 쉽게 생각하면 전달 받은 키워드 인자들이 가변 키워드 인자에 저장되어 address 파라미터가 값을 전달 받지 못한 것 처럼 보인다. 하지만 address 파라미터는 default value parameter 이기 때문에 상관 없이 않을까 생각할 수 있다.
시도해 볼 것은
결과는 여전히 오류가 난다.
def func_param_with_kwargs(name, age, address=0,**kwargs):
print("name=",end=""), print(name)
print("age=",end=""), print(age)
print("kwargs=",end=""), print(kwargs)
print("address=",end=""), print(address)
func_param_with_kwargs("정우성", "20", mobile="01012341234", address="seoul")
-->
name=정우성
age=20
kwargs={'mobile': '01012341234'}
address=seoul
정상 출력된다. 즉 default value parameter 는 non-default parameter 뒤에 존재해야하고 가변 키워드 인자는 더 뒤에 존재해야 한다.
def func(non-default parameter, default value parameter, 가변 키워드 인자)
마지막 예시를 살펴 봅시다!!
def mixed_params(name="아이유", *args, age, **kwargs, address):
print("name=",end=""), print(name)
print("args=",end=""), print(args)
print("age=",end=""), print(age)
print("kwargs=",end=""), print(kwargs)
print("address=",end=""), print(address)
mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")
--> invalid syntax
구문에러가 나왔으니까 눈에 보이는 대로 해결해 봅시다!
def mixed_params(age, address, name="아이유", *args, **kwargs):
print("name=",end=""), print(name)
print("args=",end=""), print(args)
print("age=",end=""), print(age)
print("kwargs=",end=""), print(kwargs)
print("address=",end=""), print(address)
mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")
-->TypeError: mixed_params() got multiple values for argument 'address
이번엔 구문에러가 아닌 address argument 가 여러 값을 가진다고 나오네요. 가변인수 *args 때문에 positional argument 값들이 keyword argument 값과 충돌하는 것 같습니다.
def mixed_params(age, address, name="아이유", *args, **kwargs):
print("name=",end=""), print(name)
print("args=",end=""), print(args)
print("age=",end=""), print(age)
print("kwargs=",end=""), print(kwargs)
print("address=",end=""), print(address)
mixed_params(20, "seoul", "정우성", "01012341234", "male" ,mobile="01012341234")
-->
name=정우성
args=('01012341234', 'male')
age=20
kwargs={'mobile': '01012341234'}
address=seoul
출력이 잘됩니다. 하지만 분명히 앞에서는 인수의 형태를 변경하지 않고, parameter 위치만 변경하여 적어야 하는 순서를 파악 했었다. 이번에도 방법을 찾아보자
참고 사이트를 찾아보니 Keyword-Only-Argument 라는 특수인수가 있는데 가변 위치 인수 뒤에 위치하며 non-default Keyword-Only-Argument 와 default Keyword-Only-Argument 로 나누고 가변 키워드 인수 앞에 위치한다.
그럼 keyword argument 를 가지는 address를 가변 위치 인수 뒤에, 가변 키워드 인수 앞에 옮겨보자.
def mixed_params(age, name="아이유", *args, address, **kwargs):
print("name=",end=""), print(name)
print("args=",end=""), print(args)
print("age=",end=""), print(age)
print("kwargs=",end=""), print(kwargs)
print("address=",end=""), print(address)
mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")
-->
name=정우성
args=('01012341234', 'male')
age=20
kwargs={'mobile': '01012341234'}
address=seoul
인수를 변경하지 않고 원하는 출력 값이 나왔다!!