Python | 인수와 파라미터 종류와 순서 완벽 정리

happy tiger·2022년 6월 23일
1

Python

목록 보기
3/4
post-thumbnail

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

위치 인수 (positional arguments)

함수에 인수를 순서대로 넣는 방식을 위치 인수(positional arguments)라고 한다.
아래에 위치 인수를 사용하는 함수 print_num()을 만들어보자.

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

# 위치 인수 사용. 
# 인수를 10, 20, 30 순으로 넣었으므로 순서대로 a, b, c 파라미터 자리로 넣는다.
print(10, 20, 30)   >>> 10 20 30 

리스트 언패킹 (list unpacking)

위치 인수를 여러개를 한꺼번에 넣을 땐 어떻게 해야할까?
매개변수 자체를 여러개를 줘도 되지만, 인수의 개수가 가변적이라면 리스트나 튜플을 사용하는 것이 용이하다.
리스트 언패킹은 인수의 개수가 저애지지 않은 가변 인수에 사용한다.
리스트 또는 튜플 앞에 *(에스터리스크)를 붙여 함수에 넣어주면 언패킹이 된다.
단, 이때 함수의 매개변수 개수와 리스트의 요소 개수는 같아야 한다!

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

x = [10, 20, 30]
# 가변 인수 함수
print_num(*x)   >>> 10 20 30
# print_num(*[10, 20, 30]) 처럼 직접 넣어도 된다

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

키워드 인수 (keyword argument)

키워드 인수를 사용하지 않으면, 인수의 순서와 용도를 모두 기억해야 해서 불편하다.
그래서 파이썬은 매번 인수의 순서와 용도를 기억하지 않도록 키워드 인수(keyword argument)라는 기능을 제공한다.
Keyword arguments 방식으로 파라미터 값을 전해주면 실제 파라미터 순서가 바뀌어도 괜찮다.
키워드 인수는 인수에 이름(키워드)를 붙이는 기능인데 함수 (키워드 = 값)형식으로 사용한다.

딕셔너리 언패킹 (dictionary unpacking)

키워드 인수를 여러개를 사용하고 싶다면 어떻게 해야할까?
키워드 인수의 개수만큼 파라미터를 줄 수도 있지만, 키워드 인수가 가변적일 경우를 대비하여 딕셔너리 언패킹을 사용하는 것이 용이하다.
딕셔너리를 사용해 키워드 인수로 값을 넣는 딕셔너리 언패킹을 사용하기 위해 딕셔너리 앞에 (애스터리스크 두 개)를 붙여 함수에 넣어준다.
딕셔너리에 '키워드': 값 형식으로 인수를 저장하고, 앞에
을 붙여 함수에 넣어주면 된다.
이때 딕셔너리의 키워드는 반드시 문자열 형태여야 한다.
또한, 함수의 매개변수 이름과 딕셔너리의 키 이름이 같아야 하며, 매개변수 개수와 딕셔너리 키의 개수도 같아야 한다.

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

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

personal_info(**x)
>>>이름:  홍길동
   나이:  30
   주소:  서울시 용산구 이촌동

그렇다면 딕셔너리에 *을 한 개만 붙인다면 어떻게 될까?

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

*을 한 번만 사용하는 것은 딕셔너리를 한 번 언패킹하여 key를 사용한다는 뜻이다.
따라서 딕셔너리의 값을 사용하기 위해선 **을 이용하여 딕셔너리를 두 번 언패킹해야 한다.

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

매개변수 이름은 원하는대로 지어도 되지만 관례로 keyword arguments를 줄여서 kwargs로 사용한다.
보통 **kwargs를 사용한 가변 인수 함수는 다음과 같이 함수 안에서 특정 키가 있는지 확인한 뒤 해당 기능을 만든다.

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

초깃값 지정된 파라미터(매개변수)

Default Value Parameter

지금까지 함수를 호출할 때 항상 인수를 넣어서 값을 전달했다. 그러면 인수를 생략할 수는 없을까?
초깃값이 정의된 파라미터는 함수가 호출될때 값이 넘겨지 않아도 괜찮다! 값이 넘겨지 않은 경우 초깃값이 자동으로 넘겨지게 된다.

다만, 조심해야 할점은 초깃값이 정의된 파라미터가 초깃값이 정의 되지 않은 파라미터보다 먼저 위치해 있으면 안된다는 점이다. 만일 default value parameter를 non-default value parameter 앞에 선언하면 syntax error가 납니다.

def love_you(my_name = "정우성", your_name): 
    print(f"{my_name} loves {your_name}") 
   
> Traceback (most recent call last):   
    File "python", line 1 
SyntaxError: non-default argument follows default argument

파라미터 순서

# 매개변수는 위치인수, (키워드 인수 & 가변위치인수(리스트 언패킹)) 가변 키워드 인수(딕셔너리 언패킹)
def mixed_params(age, name="아이유", *args, address, **kwargs):
    print("name=", end=""), print(name)
    print("args=", end=""), print(args)
    print("age=", end=""), print(age)
    print("kwargs=", end=""), print(kwargs)
    print("address=", end=""), print(address)

# age 뒤에 나온, default 값이 없는 키워드 인수인 address는 함수 호출시 'address = " "'형태로 작성해야함.
#만약 값인 'seoul'만 넣었을 경우 Syntax Error 발생
# SyntaxError: non-default argument follows default argument
mixed_params(20, "정우성", "01012341234", "male", mobile="01012341234", address="seoul")

❕ 이해했다면 풀어보자

1번

함수를 정의 할때 default value parameter를 non-default value parameter 앞에 정의 하면 안 되는 이유에 대해 설명해보자.

Solution

def add_three (a, b, c=10):
	return a + b + c

add_three(10, 20)  >>> 40

def add_three_1 (a=10, b, c):
	return a + b + c
>>> SyntaxError: non-default argument follows default argument

default value parameter는 입력을 받지 않아도, default값을 출력한다.
default 값 파라미터가, non-default 파라미터보다 앞에 위치한다면, non-default에 할당하려고 했던 값이 default에 할당된다.
그로 인해 default값을 적용하고 싶을 때에도 적용할 수 없어지기 때문에 default value 파라미터는 non-default 파라미터보다 항상 뒤에 위치한다.

2번

위치 인수(positional arguments)와 가변 인수(variable length arguments)의 위치를 참고 자료를 통해 조사해서 어떤 에러가 발생 하는지 확인하고, 에러를 고쳐 정상적으로 출력하자.

def func_param_with_var_args(name, *args, age):
    print("name=",end=""), print(name)
    print("args=",end=""), print(args)
    print("age=",end=""), print(age)

func_param_with_var_args("정우성", "01012341234", "seoul", 20)

Solution
위를 실행했을 때, Type Error가 발생한다.
그 이유는 age keyword에 값이 부여되지 않았기 때문이다.
만약, func_param_with_var_args("정우성", "01012341234", "seoul", age=20)으로 age키워드에 값이 부과되었다면 오류가 발생하지 않았을 것이다.
함수 정의 시, *args 뒤에 age 파라미터를 배치했을 때부터, age는 키워드 파라미터임을 전제로 하고 있다.
그렇기에 함수를 호출할 때 age는 키워드 인수를 사용해야하는 것이다.

'*args 뒤에 age 파라미터를 배치했을 때부터, age는 키워드 파라미터임을 전제로 하고 있다.'는 왜 그런 것일까?
왜 age가 위치 인수가 아닌 키워드 인수일 때만, args 뒤에 위치할 수 있을까?
`
args가변 인수는 가능한 많은 인수를 자신이 가지려고 하는 성향이 있기 때문이다. 고로 "01012341234", "seoul", 20를 모두 *args가 가지게 된다. 그로 인해 age에 부여된 값이 존재하지 않은 것이다. 이를 막기 위해 ageage=20` 형태로 키워드 인수로 사용되었어야 하지만, 위치인수를 적용했으므로 오류가 발생한 것이다.

근데 왜 Syntax Error가 아니라 Type Error가 발생한 것일까?
문법 상 잘못 작성된 함수가 아니므로 syntax error는 발생하지 않는다.
다만, age를 키워드 인수를 받도록 키워드 파라미터로 정의했지만, 함수 호출시 타입에 맞춰 키워드 인수로 받지 않고 위치 인수로 받았으므로 Type Error로 받는 것이다.

❕이를 해결하기 위해선 가변 인수가 위치 인수 뒤에 위치하면 된다.
func_param_with_var_args("정우성", "01012341234", "seoul", 20)dfunc_param_with_var_args("정우성", "01012341234", "seoul", age=20)로 변경하면 된다.

3번

가변 키워드 인수 (variable length keyword arguments)의 위치를 참고 자료를 통해 조사해서 어떤 에러가 발생 하는지 확인하고, 에러를 고쳐 정상적으로 출력하자.

def func_param_with_kwargs(name, age, **kwargs, address=0):
	print("name=",end=""), print(name)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)
    print("address=",end=""), print(address)
    
func_param_with_kwargs("정우성", "20", mobile="01012341234", address="seoul")

Solution

위의 함수 정의과정에서 Syntax Error: invalid syntax가 발생한다,
Syntax Error가 발생한다는 것은, 함수 자체 정의가 가능하지 않다는 말과도 같다.
왜냐하면 가변 키워드인 **kwargs가 default value 파라미터인 address=0 앞에 와있기 때문이다.
가변 키워드 인수가 기본값 파라미터보다 앞에 오게 되면, 함수 호출시 key= 'value'형태의 인수들을 다 빨아들이게 된다. 그렇게 되면, 가변 키워드 뒤의 기본값 파라미터는 값을 항상 할당받을 수 없게 된다.
이를 방지하기 위해 문법상 가변 키워드 파라미터는 항상 맨 뒤에 위치하도록 설정되었다.
그로 인해 syntax error가 발생하는 것이다.

고로, 이를 해결하기 위해선 가변 키워드 인수가 기본값 파라미터 뒤로 이동하면 된다.
def func_param_with_kwargs(name, age, **kwargs, address=0): -> def func_param_with_kwargs(name, age, address=0, **kwargs):

4번

위치 인수와 키워드 가변 키워드 인수 (variable length keyword arguments)의 위치를 위치를 참고 자료를 통해 조사해서 어떤 에러가 발생 하는지 확인하고, 에러를 고쳐 정상적으로 출력하자.

def mixed_params(name="아이유", *args, age, **kwargs, address):
    print("name=",end=""), print(name)
    print("args=",end=""), print(args)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)
    print("address=",end=""), print(address)

mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")

Solution

이것 또한 3번과 마찬가지로 함수 정의에서 Syntax Error가 발생한다.
그 이유는 3번과 동일한 이유로 **kwargs가 맨 뒤에 위치하지 않기 때문이다.
*args의 뒤에 위치 했을 때부터 해당 파라미터는 키워드 인수이거나, 가변 키워드 인수이다.
고로, address는 키워드 인수이다.
이어서의 설명은 3번을 참고하기 바란다.

📑 참고자료

https://getkt.com/blog/python-keyword-only-arguments/
파이썬 코딩도장
wecode - replit python

profile
호기심·끈기·성장·발전·행복·협력 ٩(๑•̀ㅂ•́)و

0개의 댓글