Python

Python에서 *args 및 **kwargs 이해하기

찐남 2022. 7. 31. 14:52

여러분들은 파이썬을 공부하시면서

*args 및 **kwargs를 포함하는

함수에 대한 문서를 볼 때 궁금해 본 적이 있나요?

 

해당 함수 내부에 전달된

이 이상한 매개변수는 무엇인가요?

 

예를 들면,

function(params, *args, **kwargs)와 같은

구문들이요.

 

초보자는 해당 함수를 호출할 때 

해당 함수를 사용하는 방법이나 

* args 및 ** kwargs 대신 

인수로 전달할 항목에 대해 혼란스러울 수 있습니다.

그래서 이번 포스팅에서는

*args 및 **kwargs, 그 의미와

함수에서의 사용을 더 잘 이해하는 데 

도움이 되는 예제와 함께 설명하겠습니다. 

그리고 예제에서 사용된 

* 및 **(Unpacking operator)를 가볍게 알아볼게요.

 

 

소개

Python의 함수는 다양한 업무에서 

특정 작업을 수행하기 위해 

재사용되는 코드를 작성하는 데 도움이 됩니다.

문자 이름을 출력하는 함수를 정의해 보겠습니다.

 

# 문자 이름을 출력하는 함수
def characters(name1, name2, name3):
    print(name1, name2, name3)

characters("철수", "영희", "희석")

 

위의 함수 " characters "는 

3개의 위치 인수 "name1", "name2", "name3"을 취하고 

단순히 이름을 출력합니다.

 

필요한 인수 수보다 

더 많이 전달하면 어떻게 될까요?

 

# 출력 인수보다 더 많은 인수 정의
characters("철수", "영희", "희석", "친구")

 

위와 같은 TypeError가 발생합니다. 

 

3개의 인수만 사용하는 함수 내부에

추가 인수가 전달되어 오류가 발생했습니다.

오류 없이 코드를 실행하려면 

함수 문자 내부에 인수를 하나 더 전달해야 합니다. 

그러나 이것은 좋은 해결책이 아닙니다.

특정 함수를 호출할 때

여러 인수를 동적으로 추가해야 하는

프로젝트에서 작업하고 있다고 가정해 보죠.

이러한 경우 어떻게 해야 할까요?

이런 상황에 대처하는 방법이 있습니다.

 

파이썬 *args 사용법

*args는 단순히 인수를 줄입니다. 

함수에서 얼마나 많은 인수를 전달해야 하는지 

확실하지 않을 때 인수로 사용됩니다.

인수 앞의 * 별표는 

인수의 길이가 가변적임을 확인합니다.

*args는 키워드가 아닌 

인수 또는 위치 인수입니다.

*args를 사용하면 함수를 호출할 때 

원하는 수의 인수를 전달할 수 있습니다.

 

# 함수 정의에서 *args 사용 예
def friends(*args):
    print(args)

friends("철수", "영희", "희석", "친구")

 

*args를 사용하면 

함수가 인수를 Tuple로 가져오기 때문에 

출력을 Tuple로 반환합니다.

 

타입을 확인해 보고 싶으면,

def friends(*args):
    print(type(args))
    print(args)

friends("철수", "영희", "희석", "친구")

 

*args와 함께 일반 인수를 사용할 수도 있습니다.

 

# 예: 함수 정의에서 일반 인수 및 인수 사용

def friends(greet, *args):
    for friend in args:
        print(f"{greet} to Python, {friend}")

greet = "Welcome"
friends(greet, "철수", "영희", "희석", "친구")

 

참고: args 대신 애완동물 이름, 친구 이름, 여자 친구 이름 등 

모든 이름을 사용할 수 있지만 

해당 이름 앞에 * 별표를 넣어야 합니다.

# 예: args 대신 다른 이름 사용

def dog(prefix, *german_shepherd):
    for breed in german_shepherd:
        print(f"그 {prefix}은 {breed}입니다.")

prefix = "동물"
dog(prefix, "강아지", "고양이", "호랑이")

 

하지만, 예외가 있습니다!

일반 인수와 함수 내부의 *args를

매개변수로 함께 전달할 때

일반 인수 앞에 *args를 전달하시 마세요.

# 예: 함수 내에서 일반 인수 앞에 *args 사용
def heroes(*characters, country):
    for character in characters:
        print(f"{character} is from {country}.")

country = "USA"
heroes(country, "Iron Man", "Captain America", "Spiderman")

 

일반 인수 앞에 

*args를 전달할 수 없기 때문에 

출력은 TypeError가 됩니다.

코드를 수정하고 

함수 내부에 전달된 매개변수의 위치를 변경하면 

오류가 발생하지 않습니다.

 

def heroes(country, *characters):
    for character in characters:
        print(f"{character}은 {country}캐릭터입니다.")

country = "한국"
heroes(country, "태권브이", "호돌이", "하니")

 

 

파이썬 **kwargs의 사용법

**kwargs는 키워드 인수에 대해 

단축되었습니다.

이제 우리는 *args에는 익숙하고

구현 방법에 대해 알고 있습니다.

**kwargs는 *args와 유사하게 작동합니다.

하지만, *args와 달리

**kwargs는 키워드 또는 명명된 인수를 사용합니다.

**kwargs에서는 

키워드 인수를 전달할 수 있도록 

(**) 이중 별표를 사용합니다.

# 예: 함수 정의에서 **kwargs 사용

def hello(**kwargs):
    print(type(kwargs))
    for key, value in kwargs.items():
        print(f"{key}은 {value}입니다.")

hello(One = "빨간색", two = "녹색", three = "파랑색")

 

**kwargs의 유형은 딕셔너리,

즉 key-value로 허용되는 인수입니다.

# 예: 함수 정의 내에서 일반 인수와 **kwargs를 함께 사용

def hello(write, **kwargs):
    print(write)
    for key, value in kwargs.items():
        print(f"{key} is {value}.")
write = "RGB stands for:"

hello(write, One = "Red", two = "Green", three = "Blue")

 

*args와 마찬가지로 

**kwargs 대신 아무 이름이나 

선택할 수 있습니다.

# 예: kwargs 대신 다른 이름 사용

def hello(write, **color):
    print(write)
    for key, value in color.items():
        print(f"{key} is {value}.")
write = "RGB stand for:"

hello(write, One = "Red", two = "Green", three = "Blue")

 

참고: 함수 정의에서 

*args 앞에 **kwargs를 전달할 수 없습니다. 

SyntaxError가 발생합니다.

 

규칙은 다음과 같습니다.  => function(params, *args, **kwargs)

 

Example

함수 정의 내에서 

세 가지 유형의 인수를 모두 사용할 수 있으며 

이 예에서는 압축 해제 연산자인 * 및 **를 

사용해 보겠습니다. 

 

def friends(greet, *args, **kwargs):
    for names in args:
        print(f"{greet} to the Programming zone {names}")
    print("\nI am Veronica and I would like to announce your roles:")
    for key, value in kwargs.items():
        print(f"{key} is a {value}")

greet = "Welcome"
names = ["Sachin", "Rishu", "Yashwant", "Abhishek"]
roles = {"Sachin":"Chief Instructor", "Rishu":"Engineer",
         "Yashwant":"Lab Technician", "Abhishek":"Marketing Manager"}

friends(greet, *names, **roles)

 

위의 코드에서

'names'와 'roles'이라는 이름의 변수를

생성했음을 알 수 있습니다.

그러나 함수에서 호출할 때 

'names' 변수 앞에 *를 사용하고 

'roles' 변수 앞에 **를 사용했습니다.


Unpacking Operator

이러한 연산자는 위에서 본 것처럼 매우 유용합니다.
* 단일 별표는 iterable 구문에 사용되고,

** 이중 별표는 딕셔너리의 구문에 사용됩니다.

 

* iterable unpacking operator 및
** dictionary unpacking 연산자는
더 많은 위치, 임의의 횟수 및 추가 상황에서
사용할 수 있습니다.
특히, 함수 호출, 이해 및 생성기 표현식
(comprehensions and generator expressions),
화면 출력에서 사용할 수 있습니다.

 

 

결론

지금까지 함수 내에서 

*args 및 **kwargs의 기본 사항을 

알아보았습니다. 

데이터가 함수에서 동적으로 제공되고 

해당 함수에서 전달되어야 하는 

인수의 수를 모르는 프로젝트에서 작업할 때 

유용할 수 있습니다. 

 

이상 파이썬에서 사용하는 

*args 및 **kwargs 구문에 대해서

알아보았습니다.

 

 

반응형