정의
함수에 Parameter가 여러개일 경우 함수 argument로 *args
를 사용하면 여러개인 Parameter를 대응할 수 있다.
naming은 임의로 *dog
, *cat
으로 지을수도 있지만, 관례적으로 *args
를 쓰는 편이다.
설명
def test(*args): print(args) >>> num_list = [1, 2, 3] >>> print( test(*num_list) == test(1, 2, 3)) (1, 2, 3) (1, 2, 3) True
궁금중을 정리해보자
test(*num_list) == test(1, 2, 3)
가 어떻게True
를 반환하는 것인가?- num_list를 그냥 넘기는게 아니라 왜
*num_list
라고 앞에*
를 붙였나?
그럼 이 2가지 궁금증을 한꺼번에 풀 수 있는 예제를 들어보고자 한다.
일단 test2라는 함수를 만들고 그 함수의 Argument로 a, b, c를 받고 출력하는 간단한 함수를 만들어보면 아래와 같다.
def test2(a, b, c): print(a, b, c)
이 test2라는 함수를 사용하기 위해서는 test2(1, 2, 3)
와 같이 사용할 수 있다.
여기까지는 다른 웬만한 프로그래밍 언어랑 별반 차이가 없어 보인다.
하지만 여기서 Python의 Magic을 부려보자.
그 매직이란게 어떤거냐면 위에서 선언한 num_list
라는 Parameter를 하나만 전달해서 에러없이 test2
를 호출하는 것이다.
어떻게 이게 가능할까?
파이썬에서 Packing, UnPacking이라는 개념을 사용하면 된다.
차근차근 살펴보자
num_list
을 가지고 test2
를 호출할려고 하면 일단 아래와 같이 호출 할 수 있다.
>>> num_list = [1, 2, 3] >>> test2(num_list[0], num_list[1], num_list[2]) print(1, 2, 3)
위와 같이 호출하면 문제없이 호출이 될 것이다.
하지만 위의 예제코드는 pythonic하지 않다.
pythonic하게 Refactoring를 해보면 아래와 같다.
>>> test2(*num_list) print(1, 2, 3)
위와같이 호출하니깐 문제없이 잘 될것이다.
앞에 *
가 붙는게 맨 처음을 test
함수를 호출할때랑 같다.
이 과정을 설명해보자면
test2(*num_list)
로 호출하면 num_list가 unpacking되어서 a=1
, b=2
, c=3
으로 전달되어서 에러 없이 잘 실행되는 것이다.
그럼 *
를 앞에 안붙이고 그냥 test2(num_list)
를 하면 어떻게 될까?
>>> test2(num_list)
TypeError: test2() missing 2 required positional arguments: 'b' and 'c'
당연한 이야기 지만 2개의 필수 Arguments를 전달 안했다고 에러가 난다.
인제 함수를 호출할때 왜 *num_list
라고 쓰는지 이해가 될 것이다.
그럼 인제 맨처음에 생겼던 궁금증을 정리해보자
test(*num_list) == test(1, 2, 3)
가 어떻게 True
를 반환하는 것인가?
test(*num_list
라고 호출할때*num_list
로 인해unpacking
이 되어서 전달*args
로 인해 다시packing
되어서 출력되기 때문에 둘다 출력결과가 같으므로True
num_list를 그냥 넘기는게 아니라 왜 *num_list
라고 앞에 *
를 붙였나?
unpacking
해서 넘길려고
결론적으로 호출할때 unpacking 실행될때 packing이라고 보면 된다.
'Programming > Python' 카테고리의 다른 글
Jupyter Notebook Add library(노트북에서 내가 쓸려는 library가 없을때 추가하는 방법) (0) | 2016.11.23 |
---|---|
Python textwrapper fill (0) | 2016.08.02 |