19. 위치 인수(Positional Argument)와 키워드 인수(Keyword Argument)
1. 키워드
- 위치 인수(Positional Argument)와 리스트(튜플) 언패킹
- 키워드 인수(Keyword Argument)와 딕셔너리 언패킹
- 가변 인수(Variable Argument)
2. 위치 인수와 키워드 인수
- 이번에는 함수에서 위치 인수, 키워드 인수를 사용하는 방법과 리스트, 딕셔너리 언패킹을 활용하는 방법을 알아보자.
3. 위치 인수와 리스트 언패킹 사용하기
- 다음과 같이 함수에 인수를 순서대로 넣는 방식을 위치 인수라고 한다.
print
에10
,20
,30
순으로 넣었으므로 출력될 때도10 20 30
으로 출력된다.
1) 위치 인수를 사용하는 함수를 만들고 호출하기
- 숫자 세 개를 각 줄에 출력하는 함수를 만들어보자.
print_numbers
에 숫자 세 개를 넣으면 각 줄에 숫자가 출력된다.
2) 언패킹 사용하기
- 이렇게 인수를 순서대로 넣을 때는 리스트나 튜플을 사용할 수도 있다.
- 다음과 같이 리스트 또는 튜플 앞에
*
(애스터리스크)를 붙여서 함수에 넣어주면 된다.
print_numbers
에10
,20
,30
이 들어있는 리스트x
를 넣고*
만 붙였는데도 숫자가 각 줄에 출력되었다.- 즉, 리스트(튜플) 앞에
*
를 붙이면 언패킹이 되어서print_numbers(10, 20, 30)
과 똑같은 동작이 된다.
- 리스트 변수 대신 리스트 앞에 바로
*
를 붙여도 동작은 같다.
- 단, 이때 함수의 매개변수 개수와 리스트의 요소 개수는 같아야 한다.
3) 가변 인수 함수 만들기
- 위치 인수와 리스트 언패킹은 인수의 개수가 정해지지 않은 가변 인수에 사용한다.
- 즉, 같은 함수에 인수 한 개를 넣을 수도 있고, 열 개를 넣을 수도 있으며, 또는 인수를 넣지 않을 수도 있다.
- 다음과 같이 가변 인수 함수는 매개변수 앞에
*
를 붙여서 만든다.
- 다음과 같이 함수를 만들 때 괄호 안에
*args
와 같이 매개변수 앞에*
를 붙인다.
print_numbers
함수에 숫자를 넣어서 호출해 보자.
- 이렇게 함수 인수 여러 개를 직접 넣어도 되고, 리스트(튜플) 언패킹을 사용해도 된다.
- 이처럼 함수를 만들 때
def print_numbers(*args):
와 같이 매개변수에*
를 붙여주면 가변 인수 함수를 만들 수 있다. - 그리고 이런 함수를 호출할 때는 인수를 각각 넣거나, 리스트(튜플) 언패킹을 사용하면 된다.
고정 인수와 가변 인수를 함께 사용하기
- 고정 인수와 가변 인수를 함께 사용할 때는 다음과 같이 고정 매개변수를 먼저 지정하고 나서 매개변수에
*
를 붙여주면 된다.
>>> def print_numbers(a, *args):
... print(a)
... print(args)
...
>>> print_numbers(1)
1
()
>>> print_numbers(1, 10, 20)
1
(10, 20)
>>> print_numbers(*[10, 20, 30])
10
(20, 30)
- 단, 이때
def print_numbers(*args, a):
처럼*args
가 고정 매개변수보다 앞쪽에 오면 안 된다. - 매개변수 순서에서
*args
는 반드시 가장 뒤쪽에 와야 한다.
4. 키워드 인수 사용하기
- 지금까지 함수에 인수를 넣을 때 값이나 변수를 그대로 넣었다.
- 그러다 보니 각각의 인수가 무슨 용도인지 알기가 어려웠다.
- 예를 들어 개인 정보를 출력하는 함수를 만들어보자.
>>> def personal_info(name, age, address):
... print("이름: ", name)
... print("나이: ", age)
... print("주소: ", address)
...
- 이 함수를 사용할 때는 첫 번째 인수에
name
, 두 번째 인수에age
, 세 번째 인수에address
를 넣어야 한다. - 만약 인수의 순서가 달라지면 잘못된 결과가 출력될 것이다.
- 이처럼 위치 인수의 경우 인수의 순서와 용도를 모두 기억해야 해서 불편하다.
- 그래서 파이썬에서는 인수의 순서와 용도를 매번 기억하지 않도록 키워드 인수라는 기능을 제공한다.
- 키워드 인수는 말 그대로 인수에 이름(키워드)를 붙이는 기능인데 다음과 같이
키워드=값
형식으로 사용한다.
personal_info
함수를 키워드 인수 방식으로 호출해 보자.
- 키워드 인수를 사용하니 함수를 호출할 때 인수의 용도가 명확하게 보인다.
- 특히 키워드 인수를 사용하면 다음과 같이 인수의 순서를 맞추지 않아도 키워드에 해당하는 값이 들어간다.
- 참고로
print
함수에서 사용했던sep
,end
도 키워드 인수이다.
5. 키워드 인수와 딕셔너리 언패킹 사용하기
- 이번에는 딕셔너리를 사용해서 키워드 인수로 값을 넣는 언패킹을 사용해 보자.
- 다음과 같이 딕셔너리 앞에
**
(애스터리크 두 개)를 붙여서 함수에 넣어준다.
- 먼저
personal_info
함수를 만든다.
>>> def personal_info(name, age, address):
... print("이름: ", name)
... print("나이: ", age)
... print("주소: ", address)
...
- 이제 딕셔너리에
"키워드": 값
형식으로 인수를 저장하고, 앞에**
를 붙여서 함수에 넣어준다. - 이때 딕셔너리의 키워드(키)는 반드시 문자열 형태가 되어야 한다.
>>> x = {"name": "홍길동", "age": 30, "address": "서울시 용산구 이촌동"}
>>> personal_info(**x)
이름: 홍길동
나이: 30
주소: 서울시 용산구 이촌동
**x
처럼 딕셔너리를 언패킹하면 딕셔너리의 값들이 함수의 인수로 들어간다.- 즉,
personal_info(name="홍길동", age=30, address="서울시 용산구 이촌동")
또는personal_info("홍길동", 30, "서울시 용산구 이촌동")
과 똑같은 동작이 된다.
- 딕셔너리 변수 대신 딕셔너리 앞에 바로
**
를 붙여도 동작은 같다.
>>> personal_info(**{"name": "홍길동", "age": 30, "address": "서울시 용산구 이촌동"})
이름: 홍길동
나이: 30
주소: 서울시 용산구 이촌동
- 딕셔너리 언패킹을 사용할 때는 함수의 매개변수 이름과 딕셔너리의 키 이름이 같아야 한다.
- 또한, 매개변수 개수와 딕셔너리 키의 개수도 같아야 한다.
- 만약 이름과 개수가 다르면 함수를 호출할 수 없다.
- 여기서는 함수를
def personal_info(name, age, address):
로 만들었으므로 딕셔너리도 똑같이 맞춰주어야 한다.
1) **
를 두 번 사용하는 이유
- 딕셔너리를 두 번
*
를 사용하는 이유는 딕셔너리는 키-값 쌍 형태로 값이 저장되어 있기 때문이다.
- 먼저 다음과 같이 *를 한 번만 사용해서 함수를 호출해 보자.
>>> x = {"name": "홍길동", "age": 30, "address": "서울시 용산구 이촌동"}
>>> personal_info(*x)
이름: name
나이: age
주소: address
personal_info
에*x
를 넣으면x
의 키가 출력된다.- 즉, 딕셔너리를 한 번 언패킹하면 키를 사용한다는 뜻이 된다.
- 따라서 다음과 같이
**
처럼 딕셔너리를 두 번 언패킹하여 값을 사용하도록 만들어야 한다.
>>> x = {"name": "홍길동", "age": 30, "address": "서울시 용산구 이촌동"}
>>> personal_info(**x)
이름: 홍길동
나이: 30
주소: 서울시 용산구 이촌동
2) 키워드 인수를 사용하는 가변 인수 함수 만들기
- 다음과 같이 키워드 인수를 사용하는 가변 인수 함수는 매개변수 앞에
**
를 붙여서 만든다.
- 함수를 만들 때 괄호 안에
**kwargs
와 같이 매개변수 앞에**
를 붙인다.
>>> def personal_info(**kwargs):
... for kw, arg in kwargs.items():
... print(kw, ": ", arg, sep="")
...
- personal_info 함수에 키워드와 값을 넣어서 실행해 보자.
- 값을 한 개 넣어도 되고, 세 개 넣어도 된다.
>>> personal_info(name="홍길동")
name: 홍길동
>>> personal_info(name="홍길동", age=30, address="서울시 용산구 이촌동")
name: 홍길동
age: 30
address: 서울시 용산구 이촌동
- 다음과 같이 딕셔너리 언패킹을 사용해도 된다.
>>> x = {"name": "홍길동"}
>>> personal_info(**x)
name: 홍길동
>>> y = {"name": "홍길동", "age": 30, "address": "서울시 용산구 이촌동"}
>>> personal_info(**y)
name: 홍길동
age: 30
address: 서울시 용산구 이촌동
- 딕셔너리에 들어있는 값이 그대로 출력되었다.
- 즉, 딕셔너리
x
는{"name": "홍길동"}
이므로personal_info(**x)
로 호출하면personal_info(name="홍길동")
과 같고, 딕셔너리y
는{"name": "홍길동", "age": 30, "address": "서울시 용산구 이촌동"}
이므로personal_info(name="홍길동", age=30, address="서울시 용산구 이촌동")
과 같다. - 이처럼 함수를 만들 때
def personal_info(**kwargs):
와 같이 매개변수에**
를 붙여주면 키워드 인수를 사용하는 가변 인수 함수를 만들 수 있고, 이런 함수를 호출할 때는 키워드와 인수를 각각 넣거나 딕셔너리 언패킹을 사용하면 된다.
- 보통
**kwargs
를 사용한 가변 인수 함수는 다음과 같이 함수 안에서 특정 키가 있는지 확인한 뒤 해당 기능을 만든다.
def personal_info(**kwargs):
if "name" in kwargs:
print("이름: ", kwargs["name"])
if "age" in kwargs:
print("나이: ", kwargs["age"])
if "address" in kwargs:
print("주소: ", kwargs["address"])
고정 인수와 가변 인수(키워드 인수)를 함께 사용하기
- 고정 인수와 가변 인수(키워드 인수)를 함께 사용할 때는 다음과 같이 고정 매개변수를 먼저 지정하고 나서 매개변수에
**
를 붙여주면 된다.
>>> def personal_info(name, **kwargs):
... print(name)
... print(kwargs)
...
>>> personal_info("홍길동")
홍길동
{}
>>> personal_info("홍길동", age=30, addres="서울시 용산구 이촌동")
홍길동
{'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**{"name": "홍길동", "age": 30, "address": "서울시 용산구 이촌동"})
홍길동
{'age': 30, 'address': '서울시 용산구 이촌동'}
- 단, 이때
def personal_info(**kwargs, name):
처럼**kwargs
가 고정 매개변수보다 앞쪽에 오면 안 된다. - 매개변수 순서에서
**kwargs
는 반드시 가장 뒤쪽에 와야 한다.
위치 인수와 키워드 인수를 함께 사용하기
- 함수에서 위치 인수를 받는
*args
와 키워드 인수를 받는**kwargs
를 함께 사용할 수도 있다.
- 다음과 같이 함수의 매개변수를
*args
,**kwargs
로 지정하면 위치 인수와 키워드 인수를 함께 사용한다.
>>> def custom_print(*args, **kwargs):
... print(*args, **kwargs)
...
>>> custom_print(1, 2, 3, sep=":", end="")
1:2:3
- 단, 이때
def custom_print(**kwargs, *args):
처럼**kwargs
가*args
보다 앞쪽에 오면 안 된다. - 매개변수 순서에서
**kwargs
는 반드시 가장 뒤쪽에 와야 한다. - 특히 고정 매개변수와
*args
,**kwargs
를 함께 사용한다면def custom_print(a, b, *args, **kwargs):
처럼 매개변수는 고정 매개변수,*args
,**kwargs
순으로 지정해야 한다.
6. 매개변수에 초깃값 지정하기
- 인수를 생략할 때는 함수의 매개변수에 초깃값을 지정하면 된다.
- 초깃값은 다음과 같이 함수를 만들 때
매개변수=값
형식으로 지정한다.
- 매개변수의 초깃값은 주로 사용하는 값이 있으면서 가끔 다른 값을 사용해야 할 때 활용한다.
- 다음과 같이
personal_info
함수에서 매개변수address
의 초깃값을"비공개"
로 지정해 보자.
>>> def personal_info(name, age, address="비공개"):
... print("이름: ", name)
... print("나이: ", age)
... print("주소: ", address)
...
address
는 초깃값이 있으므로personal_info
는 다음과 같이address
부분을 비워 두고 호출할 수 있다.
- 매개변수에 초깃값이 지정되어 있더라도 값을 넣으면 해당 값이 전달된다.
1) 초깃값이 지정된 매개변수의 위치
- 매개변수의 초깃값을 지정할 때 한 가지 주의할 점이 있는데, 다음과 같이 초깃값이 지정된 매개변수 다음에는 초깃값이 없는 매개변수가 올 수 없다.
>>> def personal_info(name, address="비공개", age):
... print("이름: ", name)
... print("나이: ", age)
... print("주소: ", address)
...
SyntaxError: non-default argument follows default argument
- 함수를 만들어보면 문법 에러가 발생하는데, 함수를 이렇게 만들어버리면
personal_info("홍길동", 30)
으로 함수를 호출했을 때30
이 어디로 들어가야 할지 알 수가 없기 때문이다.
- 다음과 같이 초깃값이 지정된 매개변수는 뒤쪽에 몰아주면 된다.
def personal_info(name, age, address="비공개"):
def personal_info(name, age=0, address="비공개"):
def personal_info(name="비공개", age=0, address="비공개"):