새로운것을 배우는 가장 좋은 방법은 실제로 사용해 보는 것이다. 간단한 예제로 multiply 함수를 만들길 원한다고 가정하자. Multiply 함수는 여러개의 argument를 인자로 받아 모두 곱한 결과를 화면에 출력한다. 하지만 이 함수가 몇개의 argument를 인자로 받는지 모른다. 그러므로 파이선 식으로 이 문제를 어떻게 해결할 수 있을까? *args에 대해 이미 알고 있다면 별로 어렵지 않다. multiply함수를 아래와 같이 정의하면서 *args를 인자로 넘겨주면 된다.
def multiply(*args):
pass
하지만 multiply 함수를 만들기 전에 파이선 인터프리터 쉘을 열어 다음 코드를 실행해본다.
def echo_args(*args):
for arg in args:
print arg
'*'는 args를 iterable로 만들어주어 for 루프를 실행해 args list 안에 있는 모든 argument를 처리할 수 있다는걸 의미한다. 예를 들어 echo_args 함수에 1,2,3을 argument로 넘겨주면 화면에 다음과 같이 출력되는걸 볼 수 있다.
>>> echo_args(1,2,3)
1
2
3
>>>
이제 *args에 대해 명확하게 이해했을것이라 생각한다. 마지막으로 multiply 함수를 완성해 본다. operator에서 mul과 functools에서 reduce를 import한다.
from operator import mul
from functools import reduce
def multiply(*args):
return reduce(mul, args)
* mul과 reduce는 *args와는 아무 관계가 없다. 단지 함수를 만드는걸 도와주는 툴일 뿐이다.
정리하자면 *args는 사용자에 의해 함수에 몇개의 argument가 넘겨질 지 모를때 사용된다.
def get_arguments(a, *args):
print "The first argument is ", a
for arg in args:
print "This argument come from args: ", arg
다음은 위의 함수 get_argements의 사용 예이다.
>>> get_arguments(13,13,13)
The first argument is 13
This argument come from args: 13
This argument come from args: 13
>>>
이제 elements라는 변수에 몇개의 element를 가지는 tuple을 만들어준다.
>>> elements = (1, 2, 3)
>>>
그리고 elements를 get_arguments에 넣어 호출해 본다.
>>> get_arguments(elements)
The first argument is (1, 2, 3)
>>>
위의 출력 결과에서 볼 수 있는것처럼 elements를 함수에 넘겨주면 elements가 a에 할당된다.
그럼 다음과 같이 하면 어떻게 되는가 보자.
>>> get_arguments(*elements)
The first argument is 1
This argument come from args: 2
This argument come from args: 3
'*'는 튜플 elements를 unpack하기 때문에 get_arguments(1,2,3)을 호출한것과 같은 의미가 된다.
----------------------
**kwargs는 *args와 마찬가지로 함수 선언에 사용되는 마법 변수지만 차이점은 함수에 keyworded argement를 넘겨줄 수 있는 것이다.
예제를 보도록 하자.
def display_stuff(**kwargs):
if kwargs is not None:
print kwargs
이제 다음과 같이 함수를 호출해 본다.
>>> display_stuff(name='Jeff', passion='development', language='python')
{'passion': 'development', 'name': 'Jeff', 'language': 'python'}
>>>
결과에서 볼 수 있는것처럼 **kwargs는 함수에 임의의 keyworded arguemts를 넘겨줘 함수 내에서 dictionary로 억세스 할 수 있게 해 준다. 예를들어 다음의 코드를 사용하면 키 'passion'에 대한 값을 쉽게 출력할 수 있다.
def display_stuff(**kwargs):
if kwargs is not None:
print kwargs['passion']
이제 다시 함수를 호출해 본다.
>>> display_stuff(name='Jeff', passion='development', language='python')
development
>>>
하지만 kwargs dictionary에 'passion' 키가 없는 경우는 어떻게 될까? KeyError가 발생하게 된다.
>>> display_stuff(error='KeyError')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in display_stuff
KeyError: 'passion'
>>>
에러를 피하고 싶으면 kwargs를 확인할 때 억세스하려는 키가 dictionary에 존재하는지 체크할 수 있다.
def display_stuff(**kwargs):
if kwargs is not None and 'passion' in kwargs:
print kwargs['passion']
함수를 위와 같이 바꾸면 'passion' 키가 없어도 더 이상 KeyError가 발생하지 않는다.
dictionary 내의 모든 키와 값을 출력하고 싶으면 다음과 같이 하면 된다.
def display_stuff(**kwargs):
if kwargs is not None:
for key, value in kwargs.items():
print key, '==>', value
이제 실행해 본다.
>>> display_stuff(name='Jeff', passion='development')
passion ==> developer
name ==> Jeff
>>>
지금까지 본 것 처럼 *args와 **kwargs는 둘의 차이점을 이해하고 잘 사용하면 파이선 프로그래밍에 매우 유용하다.
감사합니다!!! 출처 남기고 블로그에 참조하겟습니다!
답글삭제http://blog.naver.com/bellorossopomodor