brunch

You can make anything
by writing

C.S.Lewis

by 개미 Jun 23. 2018

[나름 중급 파이썬1] *args와 **kwargs

항상 헷갈리는 두 가지 다시 한번 살펴보자

이 글은 파이썬의 문법을 모르면 이해하기 어렵습니다.


python의 함수 작성 요령, 인자(argument)와 파라미터를 이해한다면 도움이 되는 내용입니다.





아니 이것은 포인터인가?!


C언어를 배울 때 가장 힘든 그것!


바로 주소값을 가지는 포인터입니다!


근데.. 사자를 피했더니 호랑이를 만났다고 ㅠㅠ


파이썬을 배우려는데 별 표시(asterisk)가?!


걱정 마세요.


파이썬에서 *, **는 주소값을 저장하는 의미가 아닙니다.


바로 여러 개의 인수를 받을 때, 키워드 인수를 받을 때 사용하는 표시입니다.







먼저 *args부터 알아보자


오늘 아주 그냥 한 방에 이걸 끝내보자고요.


*args는 *arguments의 줄임말입니다.


그러니까.. 꼭 저 단어를 쓸 필요가 없다는 말입니다.


*a 라고 써도 되고, *asdfadfads라고 적어도 되고, *myNames라고 적어도 된다는 말입니다.


이 지시어는 여러 개(복수개의)의 인자를 함수로 받고자 할 때 쓰입니다.


무슨 말인지 예시로 넘어가 보죠.



사람의 이름을 받아서 성과 이름을 분리한 후 출력하고 싶습니다.


근데 문제가 생겼습니다.


사용자가 '몇 개의' 이름을 적어 넣을지 알 수가 없는 것이죠.


이럴 때 *args를 인자로 받습니다.



다음 함수와 같이 작성했습니다.


lastName_and_FirstName 함수에서는 인자를 *Names를 받습니다.


*Names는 아무 단어로 바꿔도 상관없습니다. *a, *b, *asdaodsaos 모두 동작합니다.


args를 출력해보면 'tuple'(튜플) 형태임을 알 수 있습니다.


여러 개의 인자로 함수를 호출할 경우, 함수 내부에서는 튜플로 받은 것처럼 인식한다는 것이죠.


한 번 직접 출력해볼까요?



역시나!


튜플 형태로 들어와서 출력된다는 것을 알 수 있습니다.


이렇게 여러 개의 인자를 받기 위해서 *args의 형태로 함수 파라미터를 작성합니다.







**kwargs을 알아보자



kwargs는 keyword argument의 줄임말로 키워드를 제공합니다.


바로 예시를 볼까요?



**kwargs는 (키워드 = 특정 값) 형태로 함수를 호출할 수 있습니다.

그것은 그대로 딕셔너리 형태로 {'키워드': '특정 값'} 요렇게 함수 내부로 전달됩니다.


그렇게 전달받은 딕셔너리를 마음대로 조리하면 되겠죠?


이것을 또 다르게 사용하는 방법으로는


특정 키워드에 반응하여 함수를 작성하는 방법이 있습니다.


제 이름인 ant가 입력되었을 때는 다르게 반응하고 싶게 만들어봅시다.






키워드(딕셔너리에서 key부분의 값이)가 ant로 들어왔을 때는

"주인님 오셨군요."를 출력하여 저만의 자비스를 만들었습니다.


이제 함수를 부를 때 제 이름을 키워드로 넣으면 자비스를 부를 수 있겠네요.







우리가 사용하는 것 중에서 kwargs가 있을까요?


우리가 익숙하게 사용하는 print문에서도 특정 키워드로 다르게 동작하게 할 수 있습니다.


먼저 print의 함수의 docstring을 조회해봅시다.




print 함수를 보니 몇 가지 신기한 게 있습니다.


end='\n'가 기본값(default)으로 설정되어 있습니다.


한 번 다른 것으로 입력해볼까요?



print 함수의 설명처럼 end의 키워드 값을 바꿔줬더니 다르게 동작합니다.


원래는 하나 띄어쓰기가 매 출력문에서 붙었는데,

이제는 제가 그 값을 바꿀 수 있게 되었네요!!


이렇게 kwargs는 사용자가 원하는 방식대로 동작하게 하는 함수를 작성할 수 있습니다.



* 정확히 말하자면, keyword argument만 쓰인 것은 아닙니다. 

파라미터에 기본값을 설정해둔 것으로, 그 기본값이 \n (개행문자)로 되어있는 것입니다.




더 알아보기

조금 변형해보기

*args의 사용법은 순서도 중요합니다.


가령 이렇게 한 번 해봅시다.

여러개의 블로그 설명을 함수로 받아서 출력하고 싶습니다.


그러면 이렇게 할 수 있겠죠.

이렇게 변수를 선언한 다음에


blog_printer의 argument로 저 3개의 변수를 줘보도록 하겠습니다.


그러면 이렇게 출력되겠죠?


*args말고도 변수를 하나 더 매개변수로 추가해봅시다.



이렇게도 가능합니다. (name을 함수의 파라미터로 추가했습니다.)


이 상태에서 name과 *blogs의 순서를 바꾸면 어떻게 될까요?




엥? 순서만 바꿨는데 오류가 난다?


네 오류가 납니다.


*args는 일반 변수보다는 뒤에 위치해있어야 합니다.


파이썬은 어디서부터 어디까지를 *변수에 담을지 알 수 없습니다.


그래서 맨 앞에 특정 변수를 명시해두고, 그 뒤에는 *args로 아규먼트를 넣어줘야합니다.




*args, **kwargs를 둘 다 써보자.

둘 다 써보는 것은 어떨까요?

위의 내용을 조금 변형해서 써봅시다.


함수명 바로 아래에 다중 문자열(''')을 넣어서 함수의 docstring으로 만들어 줍니다.


저렇게 함수에다가 docstring을 넣으면 help()함수로 함수의 설명을 읽을 수 있습니다.


*blogs에는 블로그1, 블로그2, 블로그3을 아규먼트로 넣었고,

**blogs_benefits는 블로그수익1, 블로그수익2, 블로그수익3 으로 각각 키워드를 넣어서 입력했습니다.


보다시피 *blogs , **blogs_benefits를 순서대로 넣은 것을 볼 수 있습니다.


순서를 바꾸면 어떻게 될까요?

작동하지 않습니다.


이를 통해서 *변수, **변수도 순서가 있다는 것을 확인할 수 있습니다.





결론 및 요약


함수의 파라미터 순서 : 일반 변수, *변수, **변수

*변수 -> 여러개가 아규먼트로 들어올 때, 함수 내부에서는 해당 변수를 '튜플'로 처리한다.

**변수 -> 키워드='' 로 입력할 경우에 그것을 각각 키와 값으로 가져오는 '딕셔너리'로 처리한다.


충분히 복습하면서 연습해보는 것을 권장합니다.






'나름 중급 파이썬' 시리즈는


이 밖에도 꾸준히 글이 업로드 되며


Iterable, Iterator, Iteration, Generator,

디버깅, Map, Filter, Reduce, Frozenset,

global, nonlocal을 다룰 예정입니다!


(파이썬 내부 CPython은 다루지 않습니다. 아마.. 고급 파이썬에서!?)


댓글을 남겨주시면 글 작성에 큰 응원이 됩니다.


기대해주세요

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari