- Positional Arguments 와 Keyword Arguments
- Parameter Default Value과 그 순서의 의미
- 가변 인자 전달
Positional Arguments
Positional Arguments는 함수에 정의된 순서대로 인자를 보내는 방법이다.
def square(num1, num2):
...
square(2, 3)
인수의 순서를 지키지 않는다면 기대한 것과는 다른 결과가 리턴되거나 에러가 생길 수 있다.
Keyword Arguments
인수를 전달할 때 매개변수명을 명시하는 방법이다. Keyword Arguments 방식은 순서가 뒤바뀌어도 상관 없다.
square(num1 = 2, num2 = 3)
square(num2 = 3, num1 = 2) # 같은 결과 출력
square(2, num2 = 3) # 혼용 가능
square(num2 = 3, 2) # 에러
두가지 방식을 혼용하여도 되는데 이때 Positional Arguments 부분은 순서를 지켜줘야 한다.
인자가 아무것도 넘어오지 않을 때를 위해 기본값을 다음과 같이 설정할 수도 있다. 이때 주의할 점은 기본값을 가진 매개변수는 기본값이 없는 매개변수 보다 뒤에 위치해 있어야한다.
def square(num1, num2 = 3):
...
#def square(num2 = 3, num1): # 문법 오류
...
non-default value parameter가 default value parameter보다 앞에 있어야하는 이유는 간단하다.
기본값을 설정하는 이유는 인수가 넘어오지 않았을 때 값을 할당해주기 위함이다.
하지만 default value parameter가 앞에 있으면 먼저 기본값을 할당해주고 보내진 인자로 또 다시 변수에 할당하기 때문에 뒤에 나오는 non-default value parameter 는 값을 할당 받을 수 없게 된다.
def square(num2 = 3, num1):
...
square(2)
인수를 전달받을 때 인수의 개수가 가변적인 경우에는 *args, **kwargs를 사용한다.
def add(num1, num2, *args):
...
add(1, 2)
add(1, 2, 3) # args: (3)
add(1, 2, 3, 4) # args: (3, 4)
위와 같이 *args를 넣어주면 유동적인 개수의 인자를 받을 수 있으며 *뒤의 이름과 똑같은 튜플에 인자들이 저장된다.
def add(num1, num2, **kwargs):
...
add(1, 2)
add(1, 2, num3 = 3) # kwargs: {'num3': 3}
add(1, 2, num3 = 3, num4 = 4) # kwargs: {'num3': 3, 'num4': 4}
**kwargs는 가변 길이의 인자를 키워드 방식으로 전달할 수 있도록 한다.
위와 같이 인자의 이름과 값을 전달해주면 인자는 딕셔너리 타입에 저장된다.
이때 키워드 인자명이 포지셔널 인자명과 겹치지 않도록 해야한다.
def func(regular_positional, default = "arguments", *variable_length_positional, keyword_only, **variable_length_keyword):
...
파이썬 인자 종류의 순서는 다음과 같다.
일반 위치 매개변수 - 기본값 - 가변 위치 매개변수 - 키워드온리매개변수(default/non-default 무관) - 가변 키워드 매개변수
위치인수와 가변인수의 위치에 주목하여 하여 다음의 코드들을 살펴보자.
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() missing 1 required keyword-only argument: 'age'
func_param_with_var_args("정우성", "01012341234", "seoul", age=20)
# 결과:
# name=jung
# args=('1010', 'seoul')
# age=20
일반 매개변수는 가변 매개변수나 keyword only argument 보다 앞에 위치해야한다. 가변 매개 변수 뒤에 위치하게 되면 초기값을 지정하지 않은 keyword only argument로 간주하기 때문이다.
상단의 코드에서는 매개변수가 name, *args, age로 지정되어있고, 각각은 순서대로 일반 매개변수, 가변 매개변수, keyword only 매개변수이다.
따라서 함수 호출 시 인자를 전달할 때 키워드 형식으로 작성해야 오류가 발생하지 않는다.
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") # TypeError: func() got an unexpected keyword argument 'mobile'
위 코드에서는 가변 키워드 매개변수가 기본값 보다 앞에 위치해 있다. 이 경우 추가로 가변 매개변수를 인자로 넘긴다면 예상치 못한 인자값을 받았다며 에러가 발생한다.
따라서 다음과 같이 수정해야 한다.
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")
위치인수와 키워드 가변 인수의 위치를 주목하여 다음의 코드를 보자.
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")
위의 코드에서 위치 인수가 맨 앞에 있지 않고, 키워드 가변인수가 맨 뒤에 위치해있지 않아서 문법 오류가 난다.
따라서 인수 순서 규칙에 따라 다음과 같이 작성해야한다.
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")