넷플릭스 오리지널 <마이네임>으로 간단한 함수를 작성했다.
함수는 여러 parameter를 순서 기준으로 인식해서 받는데, 이를 positional arguments
방식이라고 한다.
def myName(main_char,sub_char):
print(f"주연:{main_char}, 조연:{sub_char}")
print(myName("한소희","박희순")) #"한소희"는 main_char, "박희순"은 sub_char
만약 keyword arguments
방식(parameter 이름으로 값 전달)하면 순서는 중요하지 않다.
def myName(main_char,sub_char):
print(f"주연:{main_char}, 조연:{sub_char}")
print(myName(sub_char="박희순",main_char="한소희"))
이 2가지 방법을 혼용할 수는 있지만, positional arguments
는 철저하게 자기 위치에 있어야 하기 때문에 이를 간과하면 error 가 뜬다.
그래서 항상 positional arguments
방식이 우선한다고 볼 수 있겠다.
def myName(main_char,sub_char):
print(f"주연:{main_char}, 조연:{sub_char}")
#print(myName("박희순",main_char="한소희")) #error
print(myName(main_char="한소희","박희순"))
함수 정의 시, parameter에 특정 값을 아예 부여해버릴 수도 있다.
(keyword arguments
를 함수 호출이 아닌 함수 정의 시 사용하는 방식이랄까)
이 경우, default value parameter
는 무조건 non-default value parameter
뒤에 와야 한다.
def myName(main_char,sub_char="박희순"):
print(f"주연:{main_char}, 조연:{sub_char}")
print(myName("한소희"))
처음 생각에는, default value parameter
가 앞에 오면 함수 parameter의 기본 방식인 'positional arguments' 와 충돌하기 때문이라고 봤다. 그런데 함수 호출 시 sub_char="박희순"
이라고 지정해도 error 뜨는 건 똑같다.
def myName(main_char="한소희",sub_char):
print(f"주연:{main_char}, 조연:{sub_char}")
#print(myName("박희순")) #error
#print(myName(sub_char="박희순")) #error
그렇다면, 파이썬 입장에선 non-default value parameter
가 먼저 정리되어야 전체 parameter 배정이 명확하단 얘기겠다.
non-default value parameter
를 기준으로 선처리하고(가변 인수 포함), 이 때 우선적으로 적용하는 것은 positional arguments
방식이다.variable length arguments
, 즉 가변 인수는 개수가 정해지지 않은 인수다. 우리가 함수에 전달할게 2개 인자뿐이라고 처음부터 명확하면 참 좋겠지만, 그렇지 않은 경우가 많다. 이 때 variable length arguments
를 사용한다.
def profile(main_char, sub_char, *args):
print(f"이름 : {main_char} 나이 : {sub_char}", end=" ")
print("그 외:", end=" ")
for arg in args:
print(arg, end=" ")
print()
profile("한소희","박희순","안보현") #args: "안보현"
profile("한소희","박희순","안보현","김상호","이학주","장률"...) #args는 더 늘어날 수도
각설하고,
keyword variable length arguments
는 **kw이름
과 같이 표현하며,
가변인자인데 default value가 있으므로 역시 마지막에 와줘야 한다.
def profile(main_char, sub_char, *args, **kwargs):
...
그리고 위에서 정리한 parameter 인지 규칙에 따라,
variable length arguments
는 개수가 정해지지 않았기 때문에 positional arguments
뒤에 와야 한다.
정리하면, positional args > variable length args > keyword args > keyword variable length args 순서라고 할 수 있겠다.
📌 replit checkpoint 28번에 있는 몇 개 오류를 수정해보자면 아래와 같다.
#첫 번째 오류
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)
수정 ver.
def func_param_with_var_args(name, age, *args):
...
func_param_with_var_args("정우성", 20, "01012341234", "seoul")
출력 결과는 아래와 같다.
#2번째 오류
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")
수정 ver.
def func_param_with_kwargs(name, age, address=0, **kwargs):
...
func_param_with_kwargs("정우성", "20", mobile="01012341234", address="seoul")
출력 결과는 아래와 같다.
#3번째 오류
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")
수정 ver.
def mixed_params(name, age, address, *args, **kwargs):
...
mixed_params("정우성", 20, "seoul", "01012341234", "male" ,mobile="01012341234")
출력 결과는 아래와 같다.
참고 자료:
https://getkt.com/blog/python-keyword-only-arguments/
https://stackoverflow.com/a/16933624/18229090
(Why can't non-default arguments follow default arguments?)