Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬에서 *args와 **kwargs로 임의 개수의 인수를 받는 함수 작성하는 방법

문제 상황

입력값이 두 개든 세 개든, 혹은 그 이상이든 관계없이 어떤 개수의 인수라도 유연하게 받아 처리할 수 있는 함수를 만들고 싶다면 어떻게 해야 할까요? 파이썬에서는 특별한 문법을 사용하면 아주 간단하게 해결할 수 있습니다.

해결 방법: *args로 가변 위치 인수 받기

파이썬에서 함수를 정의할 때 매개변수 이름 앞에 별표(*)를 붙이면, 호출 시 전달되는 모든 추가 위치 인수를 하나의 튜플(tuple)로 묶어 받습니다. 아래 예제는 주어진 숫자들의 평균을 구하는 함수입니다. 여기서 rest_arg는 첫 번째 인수를 제외한 나머지 숫자들이 담긴 튜플이며, 함수 내부에서는 일반적인 시퀀스처럼 자유롭게 다룰 수 있습니다.

# 주어진 숫자들의 평균을 구하는 샘플 함수
def define_average(first_arg, *rest_arg):
    average = (first_arg + sum(rest_arg)) / (1 + len(rest_arg))
    print(f"Output \n *** The average for the given numbers {average}")

# 숫자 두 개로 함수 호출
define_average(1, 2)

실행 결과

*** The average for the given numbers 1.5

이번에는 네 개의 숫자를 전달해 보겠습니다. 함수 정의를 전혀 수정하지 않고도 그대로 동작합니다.

# 더 많은 숫자로 함수 호출
define_average(1, 2, 3, 4)

실행 결과

*** The average for the given numbers 2.5

키워드 인수도 가변적으로 받기: **kwargs

위치 인수뿐만 아니라 임의 개수의 키워드 인수(keyword argument)까지 받으려면 별표 두 개(**)로 시작하는 매개변수를 사용합니다. 이 경우 전달된 키워드 인수들은 딕셔너리(dict) 형태로 저장됩니다.

def player_stats(player_name, player_country, **player_titles):
    print(f"Output \n*** Type of player_titles - {type(player_titles)}")
    titles = ' AND '.join('{} : {}'.format(key, value) for key, value in player_titles.items())

    print(f"*** Type of titles post conversion - {type(titles)}")
    stats = 'The player - {name} from {country} has {titles}'.format(name=player_name,
                                                                     country=player_country,
                                                                     titles=titles)
    return stats

player_stats('Roger Federer', 'Switzerland', Grandslams=20, ATP=103)

실행 결과

*** Type of player_titles - <class 'dict'>
*** Type of titles post conversion - <class 'str'>
'The player - Roger Federer from Switzerland has Grandslams : 20 AND ATP : 103'

위 예제에서 player_titles는 함수에 전달된 키워드 인수(Grandslams=20, ATP=103)를 담고 있는 딕셔너리입니다. 실행 결과에서 확인할 수 있듯이 타입이 dict로 출력되며, 이후 문자열로 변환되어 최종 통계 문장이 완성됩니다.

*args와 **kwargs 함께 사용하기

함수가 위치 인수와 키워드 인수를 모두 임의 개수만큼 받도록 하려면 ***를 함께 사용하면 됩니다.

def func_anyargs(*args, **kwargs):
    print(args)    # 튜플(tuple) 형태
    print(kwargs)  # 딕셔너리(dict) 형태

이 함수에서는 모든 위치 인수가 튜플인 args에 저장되고, 모든 키워드 인수는 딕셔너리인 kwargs에 저장됩니다. 참고로 argskwargs는 관례적으로 널리 쓰이는 이름일 뿐이며, 실제로는 다른 이름을 사용해도 동작에는 문제가 없습니다.