✅ Python 가변인수 와 가변키워드 인수

허정원·2021년 2월 18일
0

파이썬에서 임의의 개수의 인자를 받는 가변인수 가 존재한다.
*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 이기 때문에 상관 없이 않을까 생각할 수 있다.

시도해 볼 것은

  • 마지막 전달하는 키워드 인자positional argument로 바꿔 준다.

결과는 여전히 오류가 난다.

  • 가변 키워드 인자 순서를 맨 뒤로 보낸다.
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 parameternon-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

구문에러가 나왔으니까 눈에 보이는 대로 해결해 봅시다!

  • non-default parameter 인 age, address 를 앞으로 옮기고 default parameter 를 다음으로, 가변인수 들을 마지막에 위치 시켜 봅시다!
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 값과 충돌하는 것 같습니다.

  • address 의 keyword argument 를 position 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-Argumentdefault 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

인수를 변경하지 않고 원하는 출력 값이 나왔다!!

0개의 댓글