순서대로 값이
parameter
로 함수에 전해진다def love(my_name, your_name): print(f"{my_name} loves {your_name}") # my_name = parameter1, your_name = parameter2 love("Kim", "Lee") # 출력값 # Kim loves Lee
parameter
이름으로 맞추어서 값을 전해준다def love(my_name, your_name): print(f"{my_name} loves {your_name}") # my_name = parameter1, your_name = parameter2 love(your_name = "Lee", my_name = "Kim") # 출력값 # Kim loves Lee
Keyword arguments는 위 예시처럼 parameter 순서가 바뀌어도 괜찮다
positional arguments와 keyword arguments를 혼용하여 사용하는것도 가능하다
def love(my_name, your_name): print(f"{my_name} loves {your_name}") # my_name = parameter1, your_name = parameter2 love("Kim", your_name = "Lee") # 출력값 # Kim loves Lee
여기서 중요한 점은 keyword arguments 는 순서가 바뀌어도 상관 없지만 positional arguments 부분은 순서를 지켜줘야 한다는 것이다
함수의
parameter
에default
값을 정의해 줄 수 도 있다def love(my_name, your_name = "Lee"): print(f"{my_name} loves {your_name}") # my_name = parameter1, your_name = parameter2 love("Kim") # 출력값 # Kim loves Lee
여기서도 중요한 점은
default
값이 정의된parameter
가default
값이 정의 되지 않은parameter
보다 앞에 위치해 있으면 안된다는 것이다
- Parameter Default Value를 예시로 가져와 보자
def love(my_name, your_name = "Lee"): print(f"{my_name} loves {your_name}") # my_name = parameter1, your_name = parameter2 love("Kim") # 출력값 # Kim loves Lee
default value parameter
와non-default value parameter
의 순서를 바꿔보면def love(my_name = "Kim", your_name): print(f"{my_name} loves {your_name}") # my_name = parameter1, your_name = parameter2 love("Lee") # 출력값 # SyntaxError: non-default argument follows default argument
에러가 발생하게 된다
이유가 무엇일까?
< careerkarma 참고 >
이론적인 것을 먼저 살펴보자면 Python 함수에서 인수가 표시되어야 하는 순서는 다음과 같다
non-default
)default
)*args
)**kwargs
)이 순서를 따르지 않으면 Python은 오류 메시지를 반환한다
단순하게 공식으로만 생각해보면 2순위(default
)가 1순위(non-default
)보다 앞에 위치해 있어서 에러가 발생하게 되는 것이다
공식으로 해결하지 않고 에러가 발생하는 이유에 대해 고민해보니 non-default
를 앞에 위치시키고 input
을 주게 된다면 Python은 input
이 어느 곳으로 가야하는지 알 수 없겠다는 생각이 들었다
위 에러 내용을 다시 정리해보면
def love(my_name = "Kim", your_name):
print(f"{my_name} loves {your_name}")
# my_name = parameter1, your_name = parameter2
love("Lee") # 여기서 "Lee"는 my_name ? or your_name?
즉 my_name이 "Lee"인지 your_name이 "Lee"인지 알 수가 없기 때문인다
def love(your_name, my_name = "Kim"):
print(f"{my_name} loves {your_name}")
# my_name = parameter1, your_name = parameter2
love("Lee")
# 출력값
# Kim loves Lee
이렇게 작성하면 "Lee"는 your_name에 해당한다는 것을 바로 이해할 수 있고 my_name = "Kim"이 default
값으로 정의되어 있어서 Kim loves Lee가 올바르게 출력되는 것을 볼 수 있다 !
검색을 하다가 추가적인 정보를 발견했다
1. Positional arguments (non-default
)
2. Keyword arguments (default
)
3. Keyword-only arguments (*args
)
4. Variable keyword arguments (**kwargs
)
위 순서와 상관없이def love(my_name = "Kim", your_name):
에서*
을my_name = "Kim"
앞이나 뒤에 추가로 입력해주고love(your_name = "Lee")
처럼default
값으로input
이 되면 오류가 발생하지 않는다는 것이다
코드로 바로 살펴보자def love(*, my_name = "Kim", your_name): print(f"{my_name} loves {your_name}") love(your_name = "Lee") # 출력값 # Kim loves Lee
이유가 무엇인지는 아직은 잘 모르겠다..
추후에 관련 내용에 대해 이해하게 되면 추가로 포스팅 하겠다 !
개념 이해를 했으니 실전을 통해 지식을 다져보자
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' 값이 요구된다, 'age'의 값이 없다 로 이해할 수 있다
그러면 'age'를 모두 삭제하고 진행해보자def func_param_with_var_args(name, *args): print("name=",end=""), print(name) print("args=",end=""), print(args) func_param_with_var_args("정우성", "01012341234", "seoul", 20) # 출력값 # name=정우성 # args=('01012341234', 'seoul', 20)
정상적으로 출력되는 것을 확인 할 수 있고 'args'가
args=('01012341234', 'seoul', 20)
까지 모두 포함하고 있는 모습.
즉, 'age' 값에 해당하는 20까지 갖는 것을 알 수 있다
에러를 해결하기 위해서는 아래 두가지를 생각해 보았다
1.func_param_with_var_args("정우성", "01012341234", "seoul", 20)
을func_param_with_var_args("정우성", "01012341234", "seoul", age =20)
으로 변경해서 (age =20) 을default
로 적용시키는 방법
2. 'age'와 해당하는 값인 20을 'args'와 ("01012341234", "seoul")보다 앞에 위치시키는 방법
실제 코드로 작성해보면 두 가지 방법 모두 정상 출력 되는 것을 확인 할 수 있다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
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
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
에러 내용은 구문 오류로 Python 문법에 맞지 않다는 뜻이다
그렇다면 어느 부분에서 에러가 발생했을까?
1. Positional arguments (non-default
)
2. Keyword arguments (default
)
3. Keyword-only arguments (*args
)
4. Variable keyword arguments (**kwargs
)
문법 이론을 다시 가져와 봤다
default
값인 'address=0' 보다**kwargs
값인 'kwargs'가 앞에 위치한 것이 문제인 것을 확인 할 수 있다
def func_param_with_kwargs(name, age, **kwargs, address=0):
을def func_param_with_kwargs(name, age, address=0, **kwargs):
으로 변경하면 에러가 해결되는 것을 볼 수 있다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
이번에도 문법에 오류가 있다
2. 가변 키워드 인수 (variable length keyword arguments)의 위치 에러 수정
과 동일하게 'kwargs'가 'address' 보다 앞에 위치하고 있어서 생긴 에러이다
수정을 해주면def mixed_params(name="아이유", *args, age, 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") # 출력값 # TypeError: mixed_params() missing 1 required keyword-only argument: 'age'
여전히 에러가 뜨는데 어디서 많이 본 에러다
1. 위치 인수(positional arguments)와 가변 인수(variable length arguments)의 위치 에러 수정
과 동일하게 'age'에 해당하는 값이 없어서이다
수정을 해주면def mixed_params(name="아이유", *args, age, 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(age = 20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul") # 출력값 # SyntaxError: positional argument follows keyword argument
default
값인 (age = 20) 이non-default
값인 ("정우성", "01012341234", "male") 보다 앞에 위치하고 있어서 에러가 또다시 발생하였다 두 값의 순서를 바꿔주면 모든 에러가 해결이 되는 것을 볼 수 있다def mixed_params(name="아이유", *args, age, 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("정우성", "01012341234", "male", age = 20, mobile="01012341234", address="seoul") # 출력값 # name=정우성 # args=('01012341234', 'male') # age=20 # kwargs={'mobile': '01012341234'} # address=seoul
사실 아직까지 내가 이해한 이론적인 개념으로만 따지면 위 코드에서도
def mixed_params(name="아이유", *args, age, address, **kwargs):
를 보면default
값인 name="아이유" 가non-default
값인 age, address 보다 앞에 위치해 있기에 문제가 있어야 한다고 생각이 든다
하지만추가 정보 !!
에서*
사용 시SyntaxError
가 발생하지 않는 것을 확인했기 때문에 일단은 넘어가지만 이유가 뭔지는 꼭 알아봐야겠다