python으로 프로그래밍을 하다보면 심심찮게 *args
와 **kwargs
를 볼 수 있다.
*args
와 **kwargs
는 python에서 함수에 가변 인자를 전달할 때 사용하는 특별한 매개변수이다.*
라고 한다. *var
, **vars
로도 사용할 수 있는데, 관례처럼 *args
그리고 **kwargs
를 사용하는 것이다. *args
와 `kwargs` 는 함수를 정의할 때 사용되고, 가변 갯수의 인자들을 함수에 넣어주는 역할을 한다. 여기서의 가변 갯수의 인자는 유저들이 얼마나 많은 인자를 넣을 지 모르는 갯수가 변하는 상황**이다. 위에서 언급한 것 처럼 가변 갯수의 인자를 넣어줄 때 사용하는 *args 는 갯수가 변할 수 있는 상황에서 사용한다.
*args
는 키워드 되지 않는 개반 갯수의 인자들을 함수에 보낼 때 사용한다.코드를 예로 들어보자면
def test_var_args(f_arg, *args):
print('첫 번째 인자 : ', f_arg)
for arg in args:
print('*args의 다른 인자 : ', arg)
test_var_args('args 테스트', 'python', '가변인자', 'arg')
위는 다음과 같은 결과를 반환한다.
첫번째 인자 : args 테스트
*args의 다른 인자 : python
*args의 다른 인자 : 가변인자
*args의 다른 인자 : arg
**kwargs
는 키워드된 가변 갯수의 인자들을 함수에 보낼 때 사용한다.
**kwargs
는 함수가 이름이 지정된 인자를 처리할 때 사용해야한다.코드를 예로 보자면,
def test_var_kwargs(**kwargs):
if kwargs in not None:
for key, val in kwargs.items():
print(f"{key} == {val}")
test_var_kwargs(name='heyggun')
위는 다음과 같은 결과를 반환한다.
name == heyggun
위의 예시들은 *args
와 **kwargs
의 기본적인 사용 방법을 작성한 것이고,
전달하고자 하는 인자들의 배열이나 딕셔너리를 가지고 함수를 호출하기 위해 *args
와 **kwargs
를 사용하는 방법은 다음과 같다.
*args
, **kwargs
아래 간단한 함수가 있다.
def test_args_kwargs(arg1, arg2, arg3):
print('인자1: ', arg1)
print('인자2: ', arg2)
print('인자3: ', arg3)
위 함수에게 인자를 전달하기 위해 아래와 같이 *args
, **kwargs
를 사용한다.
# *args 사용
args = ('two', 3, 5)
test_args_kwargs(*args)
#output
인자1: two
인자2: 3
인자3: 5
# *kwargs 사용
kwargs = {"arg3" : 3, "arg2" : "two", "arg1" : 5}
# 여기서 key는 위 함수(test_args_kwargs)의 매개변수 이름과 같아야 함
test_args_kwargs(**kwargs)
#output
인자1: 5
인자2: two
인자3: 3
만약 함수에서 형식 인자(format args)
, *arg
, **kwargs
를 사용한다면 아래와 같이 사용한다.
using_function(format_args, *args, **kwargs)
*args
, **kwargs
사용일반적으로 함수의 데코레이터를 만들때 사용한다.
또한 몽키 패칭을 할 때 사용한다고도 하는데, 여기서 몽키 패칭은 런타임(실행) 중에 코드를 일부 수정하는 것을 말한다.
예를 들어 API를 호출하고 응답데이터를 반환하는 get_info 라는 함수가 있는 클래스가 존재할 때, API를 호출하고 어떤 테스트 데이터로 바꾸는 코드를 만든다면 아래와 같이 사용가능하다.
class Somethingclass:
pass
import SomethingClass
def get_info(self, *args):
return "Test data"
# 클래스 인스턴스 추가
something_instance = SomethingClass()
# get_info 메서드를 동적으로 추가
something_instance.get_info = get_info
# 추가된 메서드 호출
result = something_instance.get_info('arg1', 'arg2', 'arge3')
#결과 출력
print(result)
# output
Test data
추가된 메서드는 전달받은 위치 인자들을 'Test data'를 반환한다.
result에는 Test data가 저장되어 출력된다.
import SomethingClass
def get_info(self, **kwargs):
return kwargs
#클래스 인스턴스 생성
somthing_instance = SomethingClass()
# get_info 메서드를 동적으로 추가
somthing_instance.get_info = get_info
# 추가된 메서드 호출, 키워드 인자 전달
result = something_instance.get_info(name='heyggun', year=1992, job='ai engineer')
# 결과 출력
print(result)
# output
{'name' : 'heyggun', 'year' : 1992, 'job' : 'ai engineer'}
위 코드는 클래스에 메서드를 동적으로 추가하고 있는데, 'get_info' 라는 메서드를 정의하고 그 메서드를 'somethinclass' 클래스의 인스턴스 메서드로 추가하고 있는 것이다.
이렇게 되면 클래스의 인스턴스에서 'get_info'를 호출할 때, 추가된 키워드 인자든 'kwargs' 라는 딕셔너리로 전달된다.
*args
는 위치 인자를 튜플 형태로 받는데, 함수를 호출할 때 어떤 수의 위치 인자든 사용할 수 있게 한다.**kwargs
는 키워드 인자를 딕셔너리 형태로 받고, 함수를 호출할 때 어떤 수의 키워드 인자든 사용할 수 있게 한다고 보면 된다.