함수에 인수를 순서대로 넣는 방식을 위치 인수라고 합니다. 인수의 위치가 곧 매개변수와의 대응을 결정합니다.
def introduce(name, age, city):
print(f"이름: {name}, 나이: {age}, 도시: {city}")
# 위치 인수: 순서대로 대응
introduce("홍길동", 25, "서울")
# 이름: 홍길동, 나이: 25, 도시: 서울
인수를 순서대로 넣을 때 리스트나 튜플 앞에 애스터리스크(*)를 붙이면 요소들이 풀려서 각각의 인수로 전달됩니다. 이를 언패킹(unpacking)이라 합니다.
# 리스트 언패킹
args = ["홍길동", 25, "서울"]
introduce(*args) # introduce("홍길동", 25, "서울")과 동일
# 튜플도 동일하게 사용 가능
args_tuple = ("김철수", 30, "부산")
introduce(*args_tuple)
인수의 개수가 정해지지 않은 경우 가변 인수를 사용합니다. 매개변수 앞에 *를 붙여서 만들며, 관례적으로 args라는 이름을 사용합니다.
# *args: 개수가 정해지지 않은 위치 인수를 튜플로 받음
def add_all(*args):
print(f"받은 인수: {args}")
return sum(args)
print(add_all(1, 2, 3)) # 받은 인수: (1, 2, 3) → 6
print(add_all(10, 20, 30, 40)) # 받은 인수: (10, 20, 30, 40) → 100
*args는 전달된 인수들을 튜플로 묶어서 받습니다.
키워드 인수는 인수에 이름을 붙여서 전달하는 방식입니다. 키워드=값 형태로 사용하며, 순서에 상관없이 원하는 매개변수에 값을 전달할 수 있습니다.
def introduce(name, age, city):
print(f"이름: {name}, 나이: {age}, 도시: {city}")
# 키워드 인수: 순서와 무관하게 이름으로 대응
introduce(city="서울", name="홍길동", age=25)
# 이름: 홍길동, 나이: 25, 도시: 서울
딕셔너리 앞에 ``(애스터리스크 두 개)를 붙이면 키-값 쌍이 키워드 인수로 풀려서 전달됩니다. 이때 딕셔너리의 키는 반드시 문자열**이어야 합니다.
# 딕셔너리 언패킹
info = {"name": "홍길동", "age": 25, "city": "서울"}
introduce(**info) # introduce(name="홍길동", age=25, city="서울")과 동일
💡
*(한 번 언패킹)은 키만 풀리고,**(두 번 언패킹)은 키=값 형태로 풀립니다.
d = {"name": "홍길동", "age": 25}
# * 한 번: 키만 언패킹
print(*d) # name age
# ** 두 번: 키워드 인수로 언패킹
introduce(**d, city="서울") # name="홍길동", age=25, city="서울"
키워드 인수의 개수가 정해지지 않은 경우 매개변수 앞에 **를 붙입니다. 관례적으로 kwargs라는 이름을 사용하며, 전달된 인수들을 딕셔너리로 받습니다.
# **kwargs: 개수가 정해지지 않은 키워드 인수를 딕셔너리로 받음
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="홍길동", age=25, city="서울")
# name: 홍길동
# age: 25
# city: 서울
두 가지를 동시에 사용하면 어떤 형태의 인수든 받을 수 있는 유연한 함수를 만들 수 있습니다.
def flexible(*args, **kwargs):
print(f"위치 인수: {args}")
print(f"키워드 인수: {kwargs}")
flexible(1, 2, 3, name="홍길동", age=25)
# 위치 인수: (1, 2, 3)
# 키워드 인수: {'name': '홍길동', 'age': 25}
*args와 **kwargs의 차이를 정리하면 다음과 같습니다.
| 구분 | *args | **kwargs |
|---|---|---|
| 받는 방식 | 위치 인수 | 키워드 인수 |
| 저장 형태 | 튜플 | 딕셔너리 |
| 언패킹 대상 | 리스트, 튜플 (*) | 딕셔너리 (**) |
| 관례 이름 | args | kwargs |
매개변수에 초기값(기본값)을 지정할 수 있습니다. 매개변수=값 형태로 지정하며, 인수를 넣지 않으면 기본값이 사용되고, 값을 넣으면 해당 값이 전달됩니다.
# 매개변수 기본값 지정
def greet(name, greeting="안녕하세요"):
print(f"{greeting}, {name}님!")
greet("홍길동") # 안녕하세요, 홍길동님! (기본값 사용)
greet("홍길동", "반갑습니다") # 반갑습니다, 홍길동님! (전달한 값 사용)
기본값이 지정된 매개변수 다음에는 기본값이 없는 매개변수가 올 수 없습니다. 기본값이 있는 매개변수는 반드시 뒤쪽에 위치해야 합니다.
# ❌ 잘못된 순서: 기본값 있는 매개변수 뒤에 기본값 없는 매개변수
# def greet(greeting="안녕하세요", name): # SyntaxError!
# ✅ 올바른 순서: 기본값 없는 매개변수가 먼저
def greet(name, greeting="안녕하세요"):
print(f"{greeting}, {name}님!")