함수의 파라미터를 입력할 때 인자로 넘어온 값이 없을 경우 기본값으로 쓸 파라미터 값을 정해주는 것
예를 들면,def add(a,b=3): return a+b print(add(3)) #6
참고로 parameters는 함수 선언할 때 받아오는 값이고, arguments는 함수를 호출할 때 넘겨주는 값이다. 엄청 크게 중요하지는 않은 것 같지만 알아두면 좋다.
여기서 add
함수의 파라미터는 2개를 설정해 주었지만 argument로 넘겨주는 인자는 1개밖에 없다. 그 이유는 이미 add
함수의 파라미터에 b=3
이라고 default값을 설정해 주었기 때문이다.
그렇다고 1개만 넣어야 하냐?! 그것도 아니다. 말 그대로 default값이기 때문에 '너가 값을 안넣어 준다면 내가 알아서 설정된 기본값으로 넣을게!' 라고 하는 것이다. 즉, print(add(3,5))
라고 하면 8이 출력된다.
위 예시 코드에서
a
파라미터에는 아무 것도 설정해 주지 않았다. 저a
가 non default value parameter이다.a
의 경우에는 함수를 호출할 때 인자값을 설정해 주지 않으면 에러가 난다.
위 예시 코드에서 파라미터의 순서를 바꾸면 무슨 일이 일어나는지 살펴보자.
def add(a=2, b):
return a+b
print(add(3))
File "main.py", line 27
def addd(a=2, b):
^
SyntaxError: non-default argument follows default argument
non-default argument가 defualt argument뒤에 온다고 한다. 그럼 오류가 나나보다.
그 이유는 파이썬에서 함수를 선언할 때 파라미터의 우선 순위가 존재한다.
우선 순위는 다음과 같다.
def example(a,b,c=None,r="w",d=[],*ae,**ab):
a, b : positional parameter
c : optional parameter
r : keyword parameter
d: list parameter
*ae : keyword only
**ab : var-keyword parameter
따라서 순서를 잘 지켜서 함수를 설정해 주어야 에러가 나지 않는다.
다시 위의 예를 보면
def add(a=2, b):
return a+b
print(add(3))
File "main.py", line 27
def addd(a=2, b):
^
SyntaxError: non-default argument follows default argument
여기서 a=2
로 디폴트 값만 준 것이지 값을 변경하지 못하는 것은 아니다. 따라서 함수를 호출할 때 인자값으로 a
를 변경할 수 있는데 add(3)
에서 3이 a
를 바꿔준 것인지 b
를 바꿔준 것인지 컴퓨터는 알 수 없기 때문에 순서에 맞게 설정해 주는 것이 중요하다.
positional arguments(위치 인자) : 위치가 정해진 인자이다.
def exam(a,b,c): print(a,b,c) exam(3,1,2) #3,1,2
여기서
a, b, c
는 포지셔널 아규먼트이다. 즉, 순서가 정해져 있기 때문에 순서대로 인자가 입력이 된다.a
에는 3,b
에는 1, 마지막으로c
에는 2가 들어가게 된다.
variable length arguments(가변 인자) : 원하는 만큼 넣을 수 있는 인자
def var_len_args(a,b,*args): res = 0 for num in args: res += num print(a+b+res) var_len_args(1,2,3,3,3,3) #15
a
와b
까지는 positional arguments로 설정이 되었다. 그러나 그 뒤에*args
가 있다. 이게 바로 가변 인자를 받는 파라미터이다.a
는 1,b
는 2, 나머지 3,3,3,3은*args
에서 모조리 다 받아주는 것이다.우리가
print(1,2,3,4,5,6,7)
이라는 print함수를 쓸 때도 안에 몇개씩이나 넣을 수 있는 이유가 print함수가 가변 인자를 넣어주기 때문이다.또한 가변 인자를 keyword arguments로 넣을 수도 있다. 그럴 때는
**kwargs
를 파라미터로 여러 keyword arguments를 받는다.def keyword_arguments(a, b, **kwargs): for key, val in kwargs.items(): print(f"{key}={val}") keyword_arguments("hi", "hello", c="bye", d="good", e="happy") #결과 ''' c=bye d=good e=happy '''
이런 식으로 keyword arguments로 여러개 받아서 사용하는 가변 인자도 있다. 참고로
c="bye", d="good", e="happy"
이 부분을 받아올 때 딕셔너리로 받아오게 된다.
이전에 작성한 TIL | Get Ready for Django - 1 에서 자세하게 설명한 것이 있다.
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)
Traceback (most recent call last):
File "main.py", line 32, in <module>
func_param_with_var_args("정우성", "01012341234", "seoul", 20)
TypeError: func_param_with_var_args() missing 1 required keyword-only argument: 'age'
keyword-only argument가 하나 없다고 나온다. 하나씩 살펴보자.
func_param_with_var_args("정우성", "01012341234", "seoul", 20)
여기서 인자들은 모두 positional argument이므로 함수의 파라미터에 이 순서대로 매핑해서 넣으면 된다.
먼저, name에 "정우성"이 들어간다.
그 다음에 *args에는 계속 인자가 들어올 수 있다. "01012341234", "seoul", 20 이 세개의 인자를 모두 *args에 넣어준다.
이제 인자를 다 넣어주었으니 함수가 돌아가면 되는데 age에는 아무런 인자도 들어오지 않았다. optional parameter도 아니기 때문에 결국 에러가 난다.
여기서 문제는 바로 *args를 중간에 넣어주었기 때문에 몇개의 인자까지 넣어야 하는지 모른다.
그래서 컴퓨터는 그냥 positional arguments가 나오는 대로 모조리 집어 넣은 것이고 그 결과, 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 '''
이름과 나이를 넣어주고 나머지를 *args에 넣어주었다.
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_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")
위에 파라미터 우선 순위 부분에서 설명했듯 함수 정의가 잘못 되었다.
따라서 다음과 같이 수정하면 된다.
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")
File "main.py", line 27
def mixed_params(name="아이유", *args, age, **kwargs, address):
^
SyntaxError: invalid syntax
이 문제도 함수 파라미터 정의하는 부분이 잘못되었다.
def mixed_params(age, address, name="아이유", *args, **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,"seoul", "정우성", "01012341234", "male" ,mobile="01012341234") #결과 ''' name=정우성 args=('01012341234', 'male') age=20 kwargs={'mobile': '01012341234'} address=seoul '''
파라미터의 선언 순서와 그에 맞게 인자들의 순서도 바꾸어 주었다.
파이썬 과제를 수행하는데 적용했다. 이 부분은 매우 중요한 부분이라 꼭 알고 넘어가야 한다고 생각한다.
나중에 Django나 Flask를 배울 때 분명히 나올 것 같다.
전반적으로 다 어려웠다. *args와 **kwargs를 공부했었지만 이렇게 까지 복잡한줄은 몰랐다.