Python 파라미터 패킹

Ad Placeholder

Python 함수에서는 전달되는 인자의 개수를 미리 정하기 어려운 경우가 있습니다. 이때 여러 개의 인자를 하나로 묶어서 함수 내부에서 처리할 수 있는데, 이를 파라미터 패킹(Parameter Packing)이라고 합니다.

앞서 살펴본 파라미터 언패킹이 하나의 값을 여러 인자로 풀어 전달하는 방식이었다면, 패킹은 반대로 여러 인자를 하나의 객체로 묶는 방식입니다.

Python에서는 *args와 **kwargs를 사용해 이러한 작업을 할 수 있습니다.

파라미터 패킹이란?

먼저 일반적인 함수를 생각해 보겠습니다.

def add(a, b):
    return a + b

이 함수는 두 개의 인자를 받을 수 있습니다.

print(add(10, 20))

그런데 세 개, 네 개처럼 전달되는 인자의 개수가 계속 달라진다면 매개변수를 일일이 추가해야 합니다.

이때 *args를 사용할 수 있습니다.

def add_all(*args):
    return sum(args)

이제 원하는 개수만큼 값을 전달할 수 있습니다.

print(add_all(10, 20))
print(add_all(10, 20, 30))
print(add_all(10, 20, 30, 40))

결과:

30
60
100

여기서 전달된 여러 인자는 args라는 하나의 튜플로 묶입니다.

*args의 동작 방식

다음 코드를 보면 패킹이 어떻게 이루어지는지 쉽게 확인할 수 있습니다.

def show(*args):
    print(args)

show(10, 20, 30)

결과:

(10, 20, 30)

함수 내부의 args는 튜플입니다.

즉,

show(10, 20, 30)

으로 전달된 여러 개의 위치 인자가 내부에서는 다음과 같이 하나로 묶입니다.

args = (10, 20, 30)

이것이 *args를 이용한 파라미터 패킹입니다.

args라는 이름은 정해져 있는 것이 아니다

args라는 이름이 특별한 문법인 것은 아닙니다.

중요한 것은 앞에 붙은 *입니다.

다음과 같이 다른 이름을 사용할 수도 있습니다.

def show(*numbers):
    print(numbers)

show(10, 20, 30)

결과:

(10, 20, 30)

하지만 Python에서는 일반적으로 여러 위치 인자를 받을 때 *args라는 이름을 관례적으로 사용합니다.

따라서 다른 개발자가 코드를 봤을 때도 쉽게 이해할 수 있습니다.

일반 매개변수와 *args 함께 사용하기

*args는 일반적인 매개변수와 함께 사용할 수도 있습니다.

def calculate(operation, *numbers):
    print(operation)
    print(numbers)

호출하면 다음과 같습니다.

calculate("sum", 10, 20, 30)

결과:

sum
(10, 20, 30)

첫 번째 "sum"은 operation에 들어가고 나머지 값들은 numbers에 튜플 형태로 묶입니다.

이런 구조는 고정된 값과 여러 개의 가변적인 값을 함께 받아야 할 때 유용합니다.

**kwargs를 이용한 키워드 인자 패킹

*args가 여러 위치 인자를 묶는 방법이라면 **kwargs는 여러 키워드 인자를 묶는 방법입니다.

def show_info(**kwargs):
    print(kwargs)

다음과 같이 호출할 수 있습니다.

show_info(name="철수", age=20, major="Python")

결과:

{'name': '철수', 'age': 20, 'major': 'Python'}

여기서 kwargs는 딕셔너리입니다.

즉 여러 개의 키워드 인자가 하나의 딕셔너리로 묶입니다.

{
    "name": "철수",
    "age": 20,
    "major": "Python"
}

args와 kwargs의 차이

두 문법의 차이를 정리하면 간단합니다.

문법패킹되는 인자함수 내부 자료형
*args위치 인자튜플
**kwargs키워드 인자딕셔너리

예를 들어:

def example(*args, **kwargs):
    print(args)
    print(kwargs)

다음과 같이 호출할 수 있습니다.

example(10, 20, name="철수", age=20)

결과:

(10, 20)
{'name': '철수', 'age': 20}

10, 20은 args에 들어가고 name, age는 kwargs에 들어갑니다.

*args와 **kwargs를 함께 사용하는 이유

두 가지를 함께 사용하면 함수가 매우 유연해집니다.

예를 들어 다음과 같은 함수를 만들 수 있습니다.

def print_info(*args, **kwargs):
    print("일반 인자:", args)
    print("키워드 인자:", kwargs)

호출:

print_info(10, 20, name="철수", age=20)

결과:

일반 인자: (10, 20)
키워드 인자: {'name': '철수', 'age': 20}

이런 방식은 어떤 종류의 인자가 얼마나 전달될지 미리 정하기 어려운 함수를 만들 때 사용할 수 있습니다.

*args는 튜플이므로 일반적인 튜플처럼 사용할 수 있다

args는 튜플이기 때문에 인덱스를 사용하거나 반복문으로 순회할 수 있습니다.

def show_numbers(*args):
    for number in args:
        print(number)

show_numbers(10, 20, 30)

결과:

10
20
30

또한 sum()과 같은 내장 함수와 함께 사용할 수도 있습니다.

def calculate_sum(*args):
    return sum(args)

print(calculate_sum(10, 20, 30, 40))

결과:

100

**kwargs는 딕셔너리처럼 사용할 수 있다

kwargs는 딕셔너리이므로 키와 값을 이용해서 데이터를 처리할 수 있습니다.

def show_user(**kwargs):
    print(kwargs["name"])
    print(kwargs["age"])

show_user(name="철수", age=20)

결과:

철수
20

반복문을 사용해 모든 값을 확인할 수도 있습니다.

def show_user(**kwargs):
    for key, value in kwargs.items():
        print(key, value)

show_user(name="철수", age=20, major="Python")

결과:

name 철수
age 20
major Python

파라미터 패킹과 언패킹 비교

패킹과 언패킹은 서로 반대되는 개념입니다.

패킹:

def show(*args):
    print(args)

show(10, 20, 30)

여러 개의 인자가 하나의 튜플로 묶입니다.

언패킹:

numbers = (10, 20, 30)

show(*numbers)

하나의 튜플에 들어 있던 값이 다시 여러 개의 인자로 풀립니다.

간단하게 정리하면 다음과 같습니다.

패킹
여러 개의 인자 → 하나의 객체

언패킹
하나의 객체 → 여러 개의 인자

같은 * 기호가 사용되지만 함수를 정의할 때 사용하는지, 호출할 때 사용하는지에 따라 역할이 달라진다는 점이 중요합니다.

실무에서는 어디에 사용할까?

*args와 **kwargs는 다양한 Python 라이브러리와 프레임워크에서도 볼 수 있습니다.

특히 다른 함수에 인자를 그대로 전달하는 함수를 만들 때 유용합니다.

예를 들어 다음과 같은 형태입니다.

def wrapper(*args, **kwargs):
    return some_function(*args, **kwargs)

wrapper()에 전달된 위치 인자와 키워드 인자를 다시 some_function()에 전달하는 구조입니다.

이러한 패턴은 함수의 동작을 추가하거나 기존 함수를 감싸는 래퍼(wrapper)를 만들 때 활용할 수 있습니다.

다만 모든 함수에 *args와 **kwargs를 사용하는 것이 좋은 것은 아닙니다. 함수가 받아야 하는 매개변수가 명확하다면 일반적인 매개변수를 사용하는 편이 코드를 이해하기 쉽습니다.

파라미터 패킹 핵심 정리

이번 글의 핵심은 다음과 같습니다.

  • *args는 여러 개의 위치 인자를 하나의 튜플로 묶습니다.
  • **kwargs는 여러 개의 키워드 인자를 하나의 딕셔너리로 묶습니다.
  • args, kwargs라는 이름 자체가 특별한 것은 아닙니다.
  • *와 **가 패킹을 나타내는 핵심 문법입니다.
  • 패킹과 언패킹은 서로 반대되는 개념입니다.
  • *args, **kwargs는 인자의 개수가 유동적인 함수를 만들 때 유용합니다.

마무리

Python의 파라미터 패킹은 함수에 전달되는 여러 인자를 하나의 객체로 묶어서 처리하는 기능입니다.

가장 기본적인 형태는 다음 두 가지입니다.

def example(*args):
    pass

여러 위치 인자를 튜플로 받는 방식입니다.

def example(**kwargs):
    pass

여러 키워드 인자를 딕셔너리로 받는 방식입니다.

특히 *args와 **kwargs는 Python 라이브러리나 프레임워크의 코드를 읽다 보면 자주 만나게 되므로 기본적인 동작을 이해해 두는 것이 좋습니다.

다음 글에서는 함수 자체를 하나의 값처럼 다룰 수 있는 함수 객체(Function Object)에 대해 알아보겠습니다.


jiji

AI, Python, 생활정보와 정부 정책 정보를 쉽게 설명하는 정보 블로그입니다.

Ad Placeholder
Scroll to Top