이 그림을 다시 한 번 머릿속에 정리하며
다음의 예제를 이해해보자
자동차를 구입할때 기본 사양의 자동차를 살 수도 있고,
원하면 여러 옵션을 추가 해서 구입할 수 있습니다.
예를 들어, 가죽 의자 옵션을 추가 한다던가 해서 자동차를 구입할 수 있습니다.
예를 들어, A라는 자동차는 옵션 사항이 40개 정도 된다고 가정해 보겠습니다.
A라는 자동차를 구입하는 함수를 구현한다고 했을때,
모든 옵션 사항을 parameter로 받을려면 parameter수가 40개나 되어야 하므로
함수의 정의 부분이 너무 길어질것입니다.
게다가 대부분의 옵션 사항은 설정이 안될 확률이 높습니다.
그렇다면 40개의 parameter가 사용되지 않는데도 불구하고 정의되어야 하는 상황이 됩니다.
또한, A라는 자동차는 계속해서 업그레이드 되므로 전에는 없던 옵션이
생길 수 있습니다. 혹은 있던 옵션이 사라질 수 도 있습니다.
하지만 이미 정의된 함수를 바꾸려면 코드를 수정하고 다시 재배포 해야 하기 때문에
옵션 사항들을 그때 그때 바꿀수 있는 유동성(flexibility)가 떨어집니다.
그렇다면 이렇게 사전에 정확히 필요한 parameter 수와 구조를 알수 없는 경우는
어떻게 해야할까요?
이러한 경우의 가장 간단한 답은 바로
dictionary를 parameter로 받아서 사용하는 것임!
무슨 말인지 당연히 바로 머리에 그려지지는 않으니 실제 예시를 본다
def buy_A_car(options):
print(f"다음 사양의 자동차를 구입하십니다:")
for option in options:
print(f"{option} : {options[option]}")
options = {"seat" : "가죽", "blackbox" : "최신"}
buy_A_car(options)
> 다음 사양의 자동차를 구입하십니다:
seat : 가죽
blackbox : 최신
마치 이러면 모든 문제가 다 해결된 것만 같지만,
(원하는 옵션만 간단하게 설정할 수 있다는 장점)
이러한 문제를 해결하기 위한 것이
Keyworded variable length of arguments!
말그대로 Keyword arguments인데,
그 수가 정해지지 않고 유동적인 arguments로
위의 자동차 예시 때도 그렇지만 여러모로 분명히 쓸모가 많을 것 같은 Arguments이다
만일 위의 예시에서 Keyworded variable length of arguments를 사용했다면, 위에서 option으로 값을 주었던 부분은
**option
을 사용해서 값을 주게 된다!
option
으로 값을 주지 않고 **option
으로 값을 주었을 때 생기는 편리성은
- argument 수를 0부터 N까지 유동적으로 넘겨줄 수 있고
- keyword가 미리 정해져 있지 않기 때문에 원하는 keyword를 유동적으로 사용할 수 있고
- keyworded variable length of arguments는 dictionary 형태로 지정됨
그럼 바꾸어서 다시 써본다
def buy_A_car(**kwargs):
print(f"다음 사양의 자동차를 구입하십니다:")
for arg in kwargs:
print(f"{arg} : {kwargs[arg]}")
# 이런 식으로 함수를 정의하고 나면,
buy_A_car(seat="가죽, blackbox="최신")
buy_A_car(sunroof="다이아몬드")
buy_A_car()
# 이 중 어떠한 경우라도 사용이 가능한 것이다
# (딕셔너리 형식의 인자의 수가 2개, 1개, 0개 whatever 그냥 내 맘대로 할 수 있음)
위에서 했던 것과 방식 동일한데, keyword 사용하지 않고 순서대로 값을 전달하는 방식도 있다!
이 때는 선언 시에, * 하나만 써서 선언하면 되고
variable arguments는 tuple로 변환되어 함수에 전달된다
def print_arguments(*args):
print(f"arguments : {args}")
# 이런 식으로 함수를 정의하고 나면,
print_arguments(1, 2, 3)
print_arguments(1, 2, 3, 4, 5)
print_arguments()
# 이 중 어떠한 경우라도 사용이 가능한 것이다
# (인자의 수가 2개, 1개, 0개 whatever 그냥 내 맘대로 할 수 있음)
말그대로 위의 편리하고 유용한 함수들의 장점을 섞어놓은 형태이다
Variable arguments와 keyworded variable arguments 둘 다 사용하기!
def do_something(*args, **kwargs):
## some code here... (뭔가를 정의했다고 치자)
# 이런 식으로 함수를 정의하고 나면,
do_something (1, 2, 3, name="정우성", age=45)
do_something (1, 2, 3, 4, 5, "hello", {"주소" : "서울", "국가" : "한국"})
do_something(name ="정우성", gender ="남", height="187")
do_something(1)
do_something()
# 이 중 어떠한 경우라도 사용이 가능한 것이다
# (인자의 수가 2개, 1개, 0개 && 인자의 형태가 dictionary, 일반 인자 whatever 그냥 내 맘대로 할 수 있음)
이 개념을 이해하고 레플릿 문제를 풀 때는
진짜 거의 그냥 멱살잡혀 끌려가듯(멘토님들이 지양하라고 했던 바로 그 학습법인데 속도가 넘나 느린 것 같아서 ㅠㅠ 어쩔 수 없었다) 풀어서
이해 1도 못하고 그냥 주워들은거 총동원해서 답을 냈는데,
지금 이 문제를 보니깐
왜 sum_of_numbers
에서는 *args
로 인자를 받고,
what_is_my_full_name
에서는 **kwargs
로 인자를 받아야하는지
알겠다ㅋ