위치 인수란 함수를 호출할 때 전달되는 인자들이 매개변수에 순서대로 전달되는 인수를 의미하며 가장 일반적인 방식입니다.
가변 인수란 여러 개의 인수의 개수가 변할 수 있는 인수로 함수를 호출할 때 인수의 개수를 다양하게 바꿔가며 전달할 수 있는 방식입니다.
가변 인수(* args)
여러 개의 일반 인자를 받을 수 있는 인수로 함수 내부에서는 해당 인수를 튜플로 받은 것처럼 인식합니다.
가변 키워드 인수(** kwargs)
키워드로 이루어진 여러 개의 인자를 받을 수 있는 인수입니다.
파이썬 함수의 매개 변수에서 인수를 처리하는 순서는 아래와 같습니다.
1. 앞에서부터 순서대로 지정되는 위치 인자
2. 기본값이 정해져있는 매개 변수
3. 가변 인수(*arg) (예 - list, tuple)
4. 키워드 인수
4-1. 기본값이 정해지지 않은 키워드 인수
4-2. 기본값이 정해져있는 키워드 인수이며 *(asterisk) 뒤에 오는지로 2번과 구분
5. 가변 키워드 인수(**kwargs) (예 - dictionary)
이러한 순서가 있기 때문에 가변 인수를 사용할 때 입력하는 인수들의 순서가 매우 중요합니다.
그렇다면 default value parameter
를 non-default value parameter
앞에 정의하여 한번 호출해봅시다.
def studyClass(first="수학", second, third):
print(f"{first} 과 {second}는 좋아하고 {third}를 싫어한다.")
studyClass("과학", "영어")
# Error
File "main.py", line 1
def studyClass(first="수학", second, third):
SyntaxError: non-default argument follows default argument
호출해보니 SyntaxError
가 나타납니다.
아직 값이 없는 나머지 parameter
에 순서대로 들어가면 될 것 같은데 왜 오류가 발생할까요?
default value parameter
가 있으면 실제parameter
의 개수보다 적은parameter
를 입력하게 되며 기본적으로positional arguments
를 따르기 때문에 순차적으로 인수가 할당되어야 합니다.studyClass 함수의 첫번째 인자가 'first' 로 이동해야 하는데, 'first' 는 이미 "수학"이라는
default value
가 있습니다.
default value
가 있지만positional arguments
를 따라 'first' 와 'second' 에 "과학"과 "영어"가 이동하게 되고 마지막인 'third'가 공석이 됩니다.
parameter
내부의 인자 중default argument
가 앞 쪽에 위치하게 된다면 인자가 들어갈 곳이 모호해지는 것입니다.이러한 일들을 방지하고자 함수에서
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)
# Error
Traceback (most recent call last):
File "main.py", line 6, in <module>
func_param_with_var_args("정우성", "01012341234", "seoul", 20)
TypeError: func_param_with_var_args() missing 1 required keyword-only argument: 'age'
이 코드는 왜 오류가 났을까요?
* args
는 여러 개의 인자를 받을 수 있는 가변 인수이기 때문에 사용자가 몇 개의 인수를 입력할지 알 수 없어서* args
보다 뒤에 위치한 'age'에게 할당할 인자를 남기지 않고 모두 다 가져가게 됩니다.그렇기 때문에 뒤에 있던
non-default value parameter
를default value parameter
보다 앞에 정의해 주어야 합니다.그렇다면 age와 * args의 순서를 바꾸어 볼까요?
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("정우성", "01012341234", "seoul", 20)
아래와 같이 오류 없이 정상적으로 결과가 나왔습니다. :)
# Result name=정우성 args=('seoul', 20) age=01012341234
이번엔 가변 키워드 인수와 default value parameter가 있는 경우에 발생한 함수의 오류를 수정해봅시다.
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")
# Error
File "main.py", line 1
def func_param_with_kwargs(name, age, **kwargs, address=0):
SyntaxError: invalid syntax
이 코드는 왜 오류가 났을까요?
파이썬은
**kwargs
를 가장 마지막으로 처리하여야 하나 가변 키워드 인수인**kwargs
뒤에 default값을 가진 address가 위치해 있기 때문에 Error가 발생하였네요.이 때 address는 default값을 가지기 때문에 위치 인자인 name과 age보다 앞에 위치하지 않도록 주의해야 합니다.
그렇다면 address와 ** 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")
아래와 같이 오류 없이 정상적으로 결과가 나왔습니다. :)
# Result 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")
# Error
File "main.py", line 1
def mixed_params(name="아이유", *args, age, **kwargs, address):
SyntaxError: invalid syntax
이번엔 왜 오류가 났을까요?
위치 인수인 age를 제일 앞으로 이동해야하며 키워드 인수인 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")
짜잔! 아래와 같이 오류 없이 정상적으로 결과가 나왔습니다. :)
# Result name=정우성 args=('01012341234', 'male') age=20 kwargs={'mobile': '01012341234'} address=seoul
👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏👏