우와한 개발자

[Python] 함수 매개변수 - 기본값, *args, **kwargs, 순서 규칙

by 우와한개발자

1. 기본값을 갖는 매개변수

  • 하나 이상의 인수에 대한 기본값을 지정할 수 있음
  • 매개변수가 기본값을 가지면 함수를 호출할 때 인수를 선택적으로 지정할 수 있음
  • 기본값이 있는 매개변수는 기본값이 없는 매개변수보다 뒤에 정의하도록 권장
  • 필수 매개변수를 순서 인수로 쓰고 선택 매개변수를 키워드 인수로 많이 사용함
def func1(a,b=3):
	return a+b
	
func1(3,4)
func1(3,b=4)
func1(b=3,4) # 에러

 

1) 매개변수 기본값이 변수인 경우

  • 함수가 정의된 시점의 변수가 가진 값으로 저징
  • 이후에 변수가 바뀌어도 처음 정의했을때 값 유지
default = 10

def func(a, b=default):
    return a + b

default = 999
func(1)     # 11 → 정의 시점의 10이 유지됨

 

2) 매개변수 기본값이 리스트, 딕셔너리, 클래스의 인스턴스 등 변경 가능한 객체인경우

  • 기본값 객체가 호출마다 공유되기 때문에 의도치 않은 결과가 발생할 수 있음
def func(a, b=[]):      # 위험 : 호출마다 같은 리스트 공유
    b.append(a)
    return b

print(func(1))  # [1]
print(func(2))  # [1, 2] ← 누적됨!

def func(a, b=None):    # 권장 : None으로 기본값 설정
    if b is None:
        b = []
    b.append(a)
    return b

 

2. 순서인수와 키워드 인수

1) 순서 인수 (위치 인수)

  • 함수 호출 시 정의된 순서대로 인수를 전달하는 방식
  • 순서가 맞지 않으면 의도치 않은 결과가 나올 수 있음
def func(a, b, c):
    print(a, b, c)

func(1, 2, 3)   # ✅ 순서대로 → 1 2 3
func(3, 1, 2)   # ✅ 순서대로 → 3 1 2 (순서 바뀌면 결과도 바뀜)

 

2) 키워드 인수

  • 함수 정의시 지정한 매개변수의 이름을 통해 호출 가능
  • 순서에 상관없이 이름으로 지정하기 때문에 가독성이 높아짐
  • 함수 호출 시 키워드 인수 뒤에 위치 인수 사용 불가
def func(a, b, c):
    print(a, b, c)

func(a=1, b=2, c=3)     # ✅ 이름으로 지정
func(c=3, a=1, b=2)     # ✅ 순서 달라도 됨 → 1 2 3
func(a=1, 2, 3)         # ❌ 에러 : 키워드 인수 뒤에 위치 인수 불가

 

3. 튜플 매개변수 (*args)

1) 기본 개념

  • 매개변수 앞에 한 개를 붙이면 여러 인수를 튜플로 받음
  • args = arguments의 약자 (이름은 자유롭게 지어도 됨)
  • 자바의 가변인수(...)와 비슷
def func(*args):
    print(args)

func(1, 2, 3) # (1, 2, 3) → 튜플로 받음

 

2) 선언 위치

  • 위치 인수를 제외한 나머지를 스쿠핑하기 때문에 위치 인수보다 뒤에 정의하는 것을 권장
  • 스쿠핑(Scooping) : 나머지 인수를 한꺼번에 퍼담는다는 의미
  • *args 뒤에 오는 매개변수는 자동으로 키워드 전용 인수가 됨
def concat(*args, sep):         # *args 뒤의 sep은 키워드 전용 인수가 됨
    return sep.join(args)

concat(sep=', ', 'earth', 'mars', 'venus')  # ❌ 에러 : 키워드 인수 뒤에 위치 인수
concat('earth', 'mars', 'venus', sep=', ')  # ✅ 정상

 

3) 튜플 인수 언패킹

  • 튜플 자체를 넣으면 튜플 하나를 통째로 받아버리기 때문에 *를 붙여 언패킹해야 함
def add(*args):
    for data in args:
        print(data)

add(1, 2, 3, 4, 5)       # ✅ 정상 : 1, 2, 3, 4, 5 각각 출력

tp_data = (1, 2, 3, 4, 5)
add(tp_data)              # ❌ (1, 2, 3, 4, 5) → 튜플 자체가 하나의 인수로 들어감
add(*tp_data)             # ✅ * 붙여서 언패킹 → 1, 2, 3, 4, 5 각각 출력

 

4. 딕셔너리 매개변수 (**kwargs)

1) 기본 개념

  • 매개변수 앞에 **(두 개)를 붙이면 키워드 인수를 딕셔너리로 받음
  • 매개변수로 함수를 받고, 그 함수에 옵션을 전달할 때 주로 사용됨
def func(a, *b, **c):
	print(a)
	print(b)
	print(c)
	
func(10, 1,2,3, name='kildong',age=30)
PairGrid.map_upper(func, **kwargs) # 우상단에 그리는 함수

 

2) 선언 위치

  • 반드시 모든 매개변수 중 가장 마지막에 정의해야 함
  • args와 함께 쓸 경우 args 뒤에 위치
def func(a, *b, **c):   # ✅ 위치인수 → 튜플 → 딕셔너리 순서
    print(a)
    print(b)
    print(c)

def func(**c, a):       # ❌ 에러 : **kwargs는 반드시 마지막
    pass

def func(**c, *b):      # ❌ 에러 : **kwargs는 *args보다 뒤에
    pass

 

3) 딕셔너리 언패킹

  • 튜플 언패킹처럼 딕셔너리도 **를 붙여 언패킹할 수 있음
def func(a, b, c):
    print(a, b, c)

dict_data = {'a': 1, 'b': 2, 'c': 3}

func(dict_data)     # ❌ 딕셔너리 자체가 하나의 인수로 들어감
func(**dict_data)   # ✅ a=1, b=2, c=3 으로 언패킹되어 전달

 

5. 매개변수와 인수의 순서

  • 정의 순서 : 위치 인수 → 튜플 인수 → 키워드 인수 → 딕셔너리 인수
def func(a, b, c, *d, e=10, **f):
    pass
#         ↑        ↑    ↑      ↑
#      위치인수  튜플  키워드  딕셔너리

 

6. 자주 사용되는 패턴

def template(func, *args, **kwargs):
	print(func(*args, **kwargs)

def func1(a,b, *c, d=0, **e):
	print(a,b,c,d,e)
	result = a+b
	for item in c:
		result += item;
	return result
	
template(func1,2,3,4,5,6, d=10, f=20, g=30)
구분 문법 받는 형태 전달 방식
*args *변수명 튜플 위치 인수
**kwargs **변수명 딕셔너리 키워드 인수

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기