파이썬 *args **kwargs
파이썬 *args **kwargs는 무엇인가?
파이썬 함수를 보면 종종 *args나 **kwargs가 인자로 사용되는 것을 볼 수 있습니다. C를 배우신 분들은 *을 보면 포인터를 먼저 떠올리시겠지만 사실 이것은 포인터가 아니라 가변인수라고 합니다.
가변인수란 어떤 함수를 호출할 때 입력받을 인자가 일정하지 않을 때 사용됩니다.
우선 핵심부터 말씀드리면 *args는 인자들을 tuple형태로 받고, **kwargs는 인자들을 dict(key : value) 형태로 받아옵니다.
def args1(*args): print('args :',args) def args2(**kwargs): print('kwargs :',kwargs) args1(1,2,3) # args : (1,2,3) args2(name='daseul', addr='incheon') # kwargs : {'name':'daseul', 'addr'='incheon'}
언제 쓸 수 있는가?
자바를 배워보신 분이라면 '오버로딩'을 들어보신 적 있으실겁니다. 오버로딩을 간략하게 설명드리자면, 인자의 개수, 자료형을 다르게 정의하면 동일한 이름으로 여러개의 함수를 정의할 수 있는 것 입니다.
함수계의 hello world, 덧셈을 수행하는 add()라는 함수를 예로 오버로딩이 필요한 이유를 설명하겠습니다.
// java code class Calc{ //add1 public int add1(int a, int b){ return a+b; } /* # as python def(a,b): return a+b */ }
덧셈을 수행하는 add1()함수가 주석 add1에 작성되어 있습니다. 이 함수는 두 수 a와 b의 합을 구한 결과를 반환하고 있습니다.
하지만 두가지 숫자가 아니라 세가지 숫자를 더하고 싶다면, 네가지 숫자를 더하고 싶다면 add2(a, b, c), add3(a, b, c, d)라는 함수를 작성해야할까요?
// java code class Calc{ //add1 public int add(int a, int b){ return a+b; } //add2 public int add(int a, int b, int c){ return a+b+c; } //add3 public int add(int a, int b, int c, int d){ return a+b+c+d; } //add.... }
아니죠~ 오버로딩을 사용하면 add()라는 하나의 함수명으로 인자의 개수나 자료형에 따라 다른 동작을 수행하도록 정의할 수 있습니다.
그렇다면 혹시'함수 뒤에 숫자만 안붙혔다 뿐이지 결국 일일이 써줘야 하는것 아니냐? '라는 생각을 하셨나요?
초심자 분들은 와닿지 않으실 수 있지만 오버로딩의 중요한 포인트는 add()라는 하나의 명칭으로 호출할 수 있다는 것 입니다.
오버로딩이고 뭐고 지금부터 가변인수 *를 사용한 예를 보시면 그 생각마저 지워질 것 입니다.
def add(*params): result = 0 for p in params: result += p return result # or def add2(*params): return sum(params)
자, 느낌이 좀 오시나요? 이제 함수 안에 인자 10개가 있어도, 100개가 있어도 add(1,2,3,4 ...) 이렇게 하나의 함수로 처리할 수 있습니다.
마찬가지로 **kwargs도 DB 접속 정보 등 여러 방면에 사용할 수 있습니다.
어떻게 쓸 수 있는가?
*args와 **kwargs는 함께 사용하는 것도 가능합니다.
def args1(*args): print('args :',args) def args2(**kwargs): print('kwargs :',kwargs) def args3(*args, **kwargs): print(args) print(kwargs) args1(1,2,3) # args : (1,2,3) args2(name='daseul', addr='incheon') # kwargs : {'name':'daseul', 'addr'='incheon'} args3(1,2,c=3,d=4) #(1, 2) #{'c': 3, 'd': 4}