TIL #18. PYTHON 기본(6)

김광일·2022년 2월 5일
1

PYTHON

목록 보기
7/13
post-thumbnail

공부하면서 *args**kwargs 에 대해 이해가 되지 않았다.
갑자기 웬 별표가 튀어나와서 갑자기 날 혼란스럽게 하는가... 어떻게 사용해야하는지도 몰랐고, 내용을 봐도 뭐가 뭔지 잘 이해가 안 됐는데 블로그를 찾아보다가 갑자기 어느 순간 이해가 돼서 정리를 해본다.

1. *args

*arguments의 줄임말로 반드시 *args를 사용하지 않아도 된다.
*a, *nums ... 어떤 걸 사용해도 상관이 없다.

보통 함수에서 파라미터는 해당 자리에 하나만 들어갈 수 있지만, 이 지시어는 여러개의 파라미터를 받을 수 있다.

def numbers(*nums):
  for num in nums:
    print(num[0], num[1:3], end = " ")
  print("\n")
  print(type(nums) # tuple

numbers("1")
numbers("1", "2")
numbers("1", "2", "3")
numbers("1", "2", "3", "4")

> 1
> 1 2
> 1 2 3 
> 1 2 3 4

이렇게 여러개의 파라미터로 함수를 호출하는 경우, 튜플 형태로 들어와서 출력된다는 것을 볼 수 있다.

2. **kwargs

**keyword argument의 줄임말로, 키워드를 제공한다.
이 때엔 키워드 = 값 형태로 함수를 호출할 수 있다.

def buy_A_car(**kwargs):
    print("다음 사양의 자동차를 구입하십니다:")

    for option in kwargs:
        print(f"{option} : {kwargs[option]}")

buy_A_car(seat="가죽", blackbox="최신", tint="yes")

> 다음 사양의 자동차를 구입하십니다:
seat : 가죽
blackbox : 최신
tint : yes

이를 보면 *argstuple의 형태로 저장 되었지만, **kwargsdictionary의 형태로 저장됨을 알 수 있다.

3. MIXING ARGS AND KWARGS

*args**kwargs 는 순서도 중요하다.

(1) *args 하나만 쓰기

def car_collect(*cars):
	for car in cars:
    	print(car)

car1 = "hyundai"
car2 = "kia"
car3 = "chevrolet"

car_collect(car1, car2, car3)
> hyundai
kia
chevrolet

위와 같이 변수를 3개를 주었을 때 출력이 잘 된다.

(2) 변수 + *args

여기에 변수 하나를 추가해보면

def car_collect(name, *cars):
	print(name)
    for car in cars:
    	print(car)

my_name = "광일"
car1 = "hyundai"
car2 = "kia"
car3 = "chevrolet"

car_collect(my_name, car1, car2, car3)
> 광일
hyundai
kia
chevrolet

이렇게 가능하지만 이 상태에서 name*cars를 바꾸게 되면

TypeError: car_collect() missing 1 required keyword-only argument: 'name'

이러한 오류가 발생한다.

애초에 *args가 여러개의 변수를 담는 것인데 이 변수를 어디까지 담을지 명시가 되어있지 않기 때문에 오류가 발생하는 것이 아닐까? 하는 생각.
따라서 맨 앞에 특정 변수를 먼저 지정해주고, 그 뒤에 *args를 넣어야한다.

(3) 변수 + *args + **kwargs

마지막으로 **kwargs를 추가해보자.

def car_collect(name, *cars, **car_price):
  '''
  name : 차를 보는 사람
  *cars : 자동차 회사
  **price : 해당 차량 가격
  '''
  print(f'{name}님에게 보여드릴 차입니다.')
  for car in cars:
    print(f"{car}")
  for car, price in car_price.items():
    print(f"{car}의 가격은 {price}만원입니다.")

name = "gwangil"
car1 = "hyundai"
car2 = "kia"
car3 = "chevrolet"

car_collect(name, car1, car2, car3, casper = 1600, morning =  1300, spark = 1200)
> gwangil님에게 보여드릴 차입니다.
hyundai
kia
chevrolet
casper의 가격은 1600만원입니다.
morning의 가격은 1300만원입니다.
spark의 가격은 1200만원입니다.

*args**kwargs를 동시에 쓴다면 이런 식으로 사용할 수 있는 것이 아닐까 싶다.

그리고 한 가지 더. help(car_collect) 를 입력하게 되면

help(car_collect)
> Help on function car_collect in module __main__:

car_collect(name, *cars, **car_price)
    name : 차를 보는 사람
    *cars : 자동차 회사
    **price : 해당 차량 가격

다중 문자열(''')을 넣어서 만든 docstring을 읽어올 수 있다.

여기서 위의 (2)번과 마찬가지로 *args**kwargs의 위치를 바꾸면

SyntaxError: invalid syntax

작동하지 않게 된다.

여기서 잠깐~!! 어디선가 주워 듣기로는 공부할 때 오류를 잘 볼 줄 알아야한다고 들었다.
그렇다면 이 오류는 무엇을 뜻하는가? 파이썬에서 쓰지 않는 문법 이라는 의미이다. 즉 문법상 오류 이다.
해결책으로는 당연하게 오류난 문법의 위치를 찾아서 수정해야한다.
많은 실수들이 있겠지만 그 중에서 (1)print() 함수에서 따옴표를 생략하거나 , (2)연산시 등호를 사용했는지를 제대로 확인하지 않아 틀리는 경우가 많은 것 같다.

다시 본문으로 돌아가서 정리를 해보자면 *args, 와 **kwargw에도 순서가 있다는 것을 확인할 수 있다.


꽤나 간단해보이는데 왜 이해가 안 됐는지..참..
앞으로 닥쳐올 모르는 문제들도 언젠가는 갑자기 깨달아지는 순간이 오겠지? 항상 포기하지 말고 될 때까지 열심히 해보자.

본문은 아래 블로그를 참고로 작성하였다.
https://brunch.co.kr/@princox/180#comment

profile
부족함 없이 공부하자

0개의 댓글