함수에서 위치 인수와 키워드 인수 사용하기

Jeongyun Heo·2021년 1월 15일
0

Python

목록 보기
31/36
post-thumbnail

파이썬 코딩 도장 - 30.1 위치 인수와 리스트 언패킹 사용하기
https://dojang.io/mod/page/view.php?id=2345

위치 인수와 리스트 언패킹 사용하기

위치인수 (positional argument)

함수에 인수를 순서대로 넣는 방식을 위치 인수(positional argument)라고 한다.
즉, 인수의 위치가 정해져 있다.

언패킹 사용하기

이렇게 인수를 순서대로 넣을 때는 리스트나 튜플을 사용할 수도 있다.

리스트 또는 튜플 앞에 *(애스터리스크)를 붙여서 함수에 넣어주면 된다.

함수(*리스트)
함수(*튜플)

def print_numbers(a, b, c):
    print(a)
    print(b)
    print(c)


myList = [10, 20, 30]
print_numbers(*myList)  # 리스트 앞에 *를 붙여준다.
-------------------------------
10
20
30

리스트 또는 튜플 앞에 *를 붙이면 언패킹(unpacking)이 되어서 print_numbers(10, 20, 30)과 똑같은 동작이 된다. (tuple로 변환하여 함수에 전달된다.) 말 그대로 리스트의 포장을 푼다는 뜻이다.

가변 인수 함수 만들기

위치 인수리스트 언패킹은 인수의 개수가 정해지지 않은 가변 인수(variable argument)에 사용한다.

즉, 같은 함수에 인수 한 개를 넣을 수도 있고, 열 개를 넣을 수도 있고, 인수를 넣지 않을 수도 있다.

가변 인수 함수는 함수를 만들 때 매개변수 앞에 *를 붙여서 만든다.

def 함수이름(*매개변수):
    코드

숫자 여러 개를 받고 숫자를 각 줄에 출력하는 함수를 만들어보자.

함수를 만들 때 괄호 안에 *args와 같이 매개변수 앞에 *를 붙인다.
그리고 함수 안에서는 for로 args를 반복하면서 print로 값을 출력한다.

def print_numbers(*args):
    for arg in args:
        print(arg)

특히 이 args는 튜플이라서 for로 반복할 수 있다.

def print_numbers(*args):
    for arg in args:
        print(arg)


print_numbers(10)
---------------------------
10
def print_numbers(*args):
    for arg in args:
        print(arg)


print_numbers(10, 20, 30, 40)
-----------------------------
10
20
30
40

함수에 인수 여러 개를 직접 넣어도 되고, 리스트(튜플) 언패킹을 사용된다.

키워드 인수와 딕셔너리 언패킹 사용하기

키워드 인수 (keyword argument)

파이썬에서는 인수의 순서와 용도를 매번 기억하지 않도록 키워드 인수(keyword argument)라는 기능을 제공한다.

키워드 인수는 말 그대로 인수에 이름(키워드)을 붙이는 기능인데 키워드=값형식으로 사용한다.

키워드 인수를 사용해서 순서를 지키지 않고 값을 넣을 수 있다.

print 함수에서 사용했던 sep, end도 키워드 인수이다.

파이썬 코딩 도장 30.3 키워드 인수와 딕셔너리 언패킹 사용하기
https://dojang.io/mod/page/view.php?id=2347

이번에는 딕셔너리를 사용해서 키워드 인수로 값을 넣는 딕셔너리 언패킹을 사용해보자.

딕셔너리 앞에 **(애스터리스크 2개)를 붙여서 함수에 넣어준다.

def personal_info(name, age, address):
    print('이름: ', name)
    print('나이: ', age)
    print('주소: ', address)


x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}

personal_info(**x)  # 딕셔너리이름 앞에 ** 붙임
-------------------------------------------
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

딕셔너리의 키워드(Key)는 반드시 문자열 형태이어야 한다.

**x처럼 딕셔너리를 언패킹하면 딕셔너리의 값들이 함수의 인수로 들어간다.

딕셔너리 변수 대신 딕셔너리 앞에 바로 **를 붙여도 동작은 같다.

def personal_info(name, age, address):
    print('이름: ', name)
    print('나이: ', age)
    print('주소: ', address)


personal_info(**{'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'})
-------------------------------------------
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

딕셔너리 언패킹을 사용할 때는 함수의 매개변수 이름딕셔너리의 Key 이름이 같아야 한다. 또한, 매개변수 개수와 딕셔너리 Key의 개수도 같아야 한다.

**를 두 번 사용하는 이유

딕셔너리는 key-value 쌍 형태로 값이 저장되어 있기 때문이다.

*를 한 번만 사용해서 함수를 호출해보자

def personal_info(name, age, address):
    print('이름: ', name)
    print('나이: ', age)
    print('주소: ', address)


x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}

personal_info(*x)  # *을 한 개만 붙였다.
-------------------------------------------
이름:  name
나이:  age
주소:  address

Key가 출력되었다.

즉, 딕셔너리를 한 번 언패킹하면 키를 사용한다는 뜻이 된다.

따라서 **처럼 딕셔너리를 두 번 언패킹해서 값을 사용하도록 만들어야 한다.

키워드 인수를 사용하는 가변 인수 함수 만들기

이번에는 키워드 인수를 사용하는 가변 인수 함수를 만들어보자.

키워드 인수를 사용하는 가변 인수 함수는 매개변수 앞에 **를 붙여서 만든다.

def 함수이름(**매개변수):  # 매개변수 앞에 ** 붙임
    코드

함수를 만들 때 괄호 안에 **kwargs와 같이 매개변수 앞에 **를 붙인다.

함수 안에서는 forkwargs.items()를 반복하면서 print로 값을 출력한다.

items() 함수Key와 Value의 쌍튜플로 묶은 값을 dict_items 객체로 돌려준다.

매개변수 이름은 원하는 대로 지어도 되지만 관례적으로 keyword arguments를 줄여서 kwargs로 사용한다.

def personal_info(**kwargs):
    for kw, arg in kwargs.items():  
        print(kw, ': ', arg, sep='')

특히 이 kwargs는 딕셔너리라서 for로 반복할 수 있다.

personal_info 함수에 키워드와 값을 넣어서 실행해보자.
값을 한 개 넣어도 되고, 세 개 넣어도 된다.

def personal_info(**kwargs):
    for kw, arg in kwargs.items():  
        print(kw, ': ', arg, sep='')


personal_info(name='홍길동', age=30, address='서울시 용산구 이촌동')
--------------------------------------------
name: 홍길동
age: 30
address: 서울시 용산구 이촌동

인수를 직접 넣어도 되고, 딕셔너리 언패킹을 사용해도 된다. 다음과 같이 딕셔너리를 만들고 앞에 **를 붙여서 넣어보자.

def personal_info(**kwargs):
    for kw, arg in kwargs.items():
        print(kw, ': ', arg, sep='')


x = {'name': '홍길동'}
personal_info(**x)
--------------------------------------
name: 홍길동

딕셔너리 x는 {'name': '홍길동'}이므로 personal_info(**x)로 호출하면 personal_info(name='홍길동')과 같다.

이처럼 함수를 만들 때 def personal_info(**kwargs):와 같이 매개변수 앞에 **를 붙여주면 키워드 인수를 사용하는 가변 인수 함수를 만들 수 있다.

그리고 이런 함수를 호출할 때는 키워드와 인수를 각각 넣거나 딕셔너리 언패킹을 사용하면 된다.

보통 **kwargs를 사용한 가변 인수 함수는 다음과 같이 함수 안에서 특정 Key가 있는지 확인한 뒤 해당 기능을 만든다.

def personal_info(**kwargs):
    if 'name' in kwargs:  # in 으로 딕셔너리 안에 특정 Key가 있는지 확인
        print('이름: ', kwargs['name'])
    if 'age' in kwargs:
        print('나이: ', kwargs['age'])
    if 'address' in kwargs:
        print('주소: ', kwargs['address'])

고정 인수와 가변 인수(키워드 인수)를 함께 사용하기

고정 인수와 가변 인수(키워드 인수)를 함께 사용할 때는 다음과 같이 고정 매개변수를 먼저 지정하고, 그 다음 매개변수에 **를 붙여주면 된다.

단, 이때 def personal_info(**kwargs, name):처럼 **kwargs가 고정 매개변수보다 앞쪽에 오면 안 된다. 매개변수 순서에서 **kwargs반드시 가장 뒤쪽에 와야 한다.

def personal_info(name, **kwargs):
    print(name)
    print(kwargs)


personal_info('홍길동')
----------------------------------------
홍길동  # print(name)
{}    # print(kwargs)
def personal_info(name, **kwargs):
    print(name)
    print(kwargs)


personal_info('홍길동', age=30, address='서울시 용산구 이촌동')
--------------------------------------------------------
홍길동  # print(name)
{'age': 30, 'address': '서울시 용산구 이촌동'}  # print(kwargs)
def personal_info(name, **kwargs):
    print(name)
    print(kwargs)


personal_info(**{'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'})
--------------------------------------------------------------------------
홍길동  # print(name)
{'age': 30, 'address': '서울시 용산구 이촌동'}  # print(kwargs)

위치 인수와 키워드 인수를 함께 사용하기

함수에서 위치 인수를 받는 *args키워드 인수를 받는 **kwargs를 함께 사용할 수도 있다.

대표적인 함수가 print인데 print는 출력할 값을 위치 인수로 넣고, 키워드 인수로 sep, end 등을 넣는다.

다음과 같이 함수의 매개변수를 *args, **kwargs로 지정하면 위치 인수키워드 인수를 함께 사용한다.

단, 이때 def custom_print(**kwargs, *args):처럼 **kwargs*args보다 앞쪽에 오면 안 된다. 매개변수 순서에서 **kwargs반드시 가장 뒤쪽에 와야 한다.

특히 고정 매개변수*args, **kwargs를 함께 사용한다면 def custom_print(a, b, *args, **kwargs):처럼 매개변수는 고정 매개변수, *args, **kwargs 순으로 지정해야 합니다.

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


custom_print(1, 2, 3, sep=':', end='')
---------------------------------------
1:2:3

위치 인수와 키워드 인수를 둘 다 사용하면 어떠한 형태와 수의 argument도 허용 가능한 함수가 된다.

즉, parameter에 있어서 굉장히 유동적인 함수가 되는 것이다.

0개의 댓글