파이썬의 라이브러리 안을 보다 보면 *args나 **kwargs와 같은 함수의 파라미터 부분에서 보인다. 마치 c++에서 아래와 같은 구문과 유사하게 보인다. 하지만 다행히 파이썬에서 *와 **는 포인터를 의미하는 것은 아니다. 파이썬에선 주소에 직접 접근해서 코딩을 하지는 못하기 때문이다. 아래는 c++ 코드이다.
int main(int argc, char **argv)
{
return 0;
}
c++에서 argc는 argument의 개수, argv는 배열 형태로 argv[0]에는 실행 파일명이 저장되고 이후 argv[1], argv[2]...에는 입력한 인자(argument)값들이 들어가게 된다.
참고로 매개변수(parameter)와 전달인자(argument)는 혼용해서 사용하기도 하는데 일반적으로 매개변수는 함수의 정의 부분에 나열된 변수들을 지칭하고, 전달 인자는 함수를 호출할 때 파라미터에 해당하는 부분에 대입하는 변수들을 지칭하며, 매개변수의 변수는 variable로, 전달 인자의 값은 value로 부르는 것이 일반적이다.
다시 돌아와 파이썬에서 *args는 arguments를 줄인 말인데 사실 꼭 저 형태가 아니더라도 *asdf, *wqdadff와 같이 앞에 *만 붙으면 뒤에 다른 문자가 와도 우리가 원하는 기능으로 사용할 수 있다. 심지어 한글도 된다.
a=b=c=d=e=f=g=1
def args_test(temp, *인자값):
print(temp)
print(인자값)
for val in range(len(인자값)):
print(val)
args_test("args", a, b, c, d, e, f, g)
이렇게 동작할 수 있는 이유는 인자 값을 받으면 tuple형태로 값들을 받기 때문이다.
다음은 **kwargs이다. 이는 keyword arguments의 줄임말이다. 키워드가 들어갔으니 당연히 dictionary 형태로 반환해 줄 것이라 어느 정도 짐작은 가능하다. 또한 한글로도 작성할 수 있다.
a=b=c=d=e=f=g=1
def kwargs_test(temp, **키워드인자값):
print(temp)
print(키워드인자값)
for val in range(len(키워드인자값)):
print(val)
kwargs_test("kwargs", a=a, b=b, c=c, d=d, e=e, f=f, g=g)
위 두 방법 모두 파이썬 함수의 파라미터 초기화를 할 때 순서가 중요한 것 처럼 순서는 지켜서 작성해주어야 한다. 아래처럼 작성하면 모두 error를 반환할 것이다.
a=b=c=d=e=f=g=1
def func_init_test(temp2=1, temp):
print(temp)
print(temp2)
func_init_test("func_init")
def args_test(*인자값, temp):
print(temp)
print(인자값)
for val in range(len(인자값)):
print(val)
args_test("args", a, b, c, d, e, f, g)
def kwargs_test(**키워드인자값, temp):
print(temp)
print(키워드인자값)
for val in range(len(키워드인자값)):
print(val)
kwargs_test("kwargs", a=a, b=b, c=c, d=d, e=e, f=f, g=g)
def kwargs_test2(**키워드인자값, *인자값):
print(인자값)
print(키워드인자값)
kwargs_test2(a=a, b=b, c=c, d=d, e=e, f=f, g=g, "args1", "args2")
따라서 아래와 같이 순서를 지켜서 작성해주어야 한다.
a=b=c=d=e=f=g=1
def func_init_test(temp, temp2=1):
print(temp)
print(temp2)
func_init_test("func_init")
def args_test(temp, *인자값):
print(temp)
print(인자값)
for val in range(len(인자값)):
print(val)
args_test("args", a, b, c, d, e, f, g)
def kwargs_test(temp, **키워드인자값):
print(temp)
print(키워드인자값)
for val in range(len(키워드인자값)):
print(val)
kwargs_test("kwargs", a=a, b=b, c=c, d=d, e=e, f=f, g=g)
def kwargs_test2(*인자값, **키워드인자값):
print(인자값)
print(키워드인자값)
kwargs_test2("args1", "args2", a=a, b=b, c=c, d=d, e=e, f=f, g=g)
위 예시들은 테스트용이므로 한글로 args나 kwargs를 한글로 사용했지만 관습적으로 행해오던 것들을 굳이 바꿔서 자기 코드에 사용하게 되면 협업을 하거나 추후 유지보수를 할 때 헷갈릴 수 있으므로 추천하지는 않는다.