default value parameter를 non-default value parameter 를 앞에 두면 안되는 이유??
매우 간단한 plus란 함수를 만들어 보았다.
def plus(a, b, c):
return a + b + c
print(plus(1, 2, 3))
>>> 6
위와같이 plus함수는 전달받은 인자를 모두를 더하는 간단한 함수이다.
하지만 만약 c 의 값이 4로 고정되어 있다고 가정할때, 우리는 c 에 defalut 값을 지정해줄 수 있다.
def plus(a, b, c=4):
return a + b + c
print(plus(1, 2))
>>> 7
위와같이 c=4
로 c에게 default 값을 지정해줄 경우, 인자와 매개변수의 수를 맞춰주지 않아도 함수가 제대로 작동하는 모습을 볼 수있다.
하지만 매개변수에 default값을 주었다고해서 새로운 인자를 전달할 수 없다는 뜻은 아니다.
def plus(a, b, c=4):
return a + b + c
print(plus(1, 2, 5))
>>> 8
위와같이 default값이 저장되어있는 매개변수 c에게 5라는 인자를 주었을 경우에도 정상적으로 작동하는 모습을 볼 수 있다.
여기서 우리는 default value parameter를 non-default value parameter 를 앞에 두면 안되는 이유를 어느정도 유추해 볼 수 있다.
def plus(c=4, a, b):
return a + b + c
print(plus(1, 2))
>>> SyntaxError: non-default argument follows default argument
위와같이 default 값이 지정되어있는 매개변수를 그렇지않은 매개변수 앞에 두게 되면 에러가 발생한다. 그 이유는 무엇일까??
우리는 조금전에 default 값이 지정되어 있는 매개변수도 새로운 인자를 받을 수 있다는 사실을 배웠다.
그로 인하여 우리가주는 인자인 (1, 2)는 defalut값이 지정되어 있는 매개변수로부터 순서대로 들어가야 하는지, 아니면 defalut값이 지정되어있는 매개변수를 제외하고 다른 곳으로 들어가야하는지 알 수없기 때문에 오류를 출력하는 것이다.
그렇기 때문에 우리는 항상여기서 우리는 non-default value parameter를 default value parameter 앞에 두어야 하는 것이다.
다음과같은 예제를 살펴보자.
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'
위 예제에서 오류가 난 이유는 무엇일까??
바로 가변인수의 특성때문인다. 가변인수는 전달받는 인수의 개수가 정해져있지않고, 여러개의 인수를 전달받을수 있기때문이다.
위 예제어서 *arg
라는 가변인수는
("01012341234", "seoul", 20)
위 세개의 인수를 모두 전달받는다. 그렇기 때문에 age
라는 매개변수에 넣을 인자가 없기 때문에 오류를 출력하는 것이다.
def func_param_with_var_args(name, age, *args):
print("name=",end=""), print(name)
print("args=",end=""), print(args)
print("age=",end=""), print(age)
func_param_with_var_args("정우성", 20, "01012341234", "seoul")
>>> name=정우성
args=('01012341234', 'seoul')
age=20
위와같이 가변인수를 위치인수 뒤에 두어야 함수가 정상적으로 작동한다는 것을 알 수 있다.
address와 같은 키워드인수는
*arg
가 없으면 위치인수와 같은 성질을 가진다.*arg
를 기준으로 좌측에는 기본적인 위치인수이고, 우측은 키워드인수이다.
다음과같은 예제를 살펴보자.
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")
>>> SyntaxError: invalid syntax
위 예제에서 오류가 난 이유는 무엇일까?
가변 키워드 인수(variable length keyword arguments) 는 임의의 개수의 키워드인자를 받고, 값을 Dictionary 형태로 저장한다.
따라서 **kwargs
라는 가변 키워드 인수는
(mobile="01012341234", address="seoul")
이 두가지 키워드 값을
{mobile : "01012341234"}, {adress : "seoul"}
이렇게 dictionary형태로 모두 저장해버린 것이다.
그렇기 떄문에 address
라는 매개변수는 전달받은 인자가 사라져 버렸기때문에 함수는 오류를 출력한 것이다.
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
따라서 위와같이 가변키워드 인수를 뒤로 옮겨주면 정상적으로 출력되는 모습을 볼 수있다.
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")
>>>SyntaxError: invalid syntax
그렇다면 우리는 지금까지 배운내용을 이용해서 위예제의 오류를 없앨 수 있을것이다.
def mixed_params(age, name="아이유", *args, address=0, **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