Python 3.8: Assignment Expressions, a.k.a Walrus Operator

이 내용은 Effective Python(2nd) 에서 가져왔다.

Python 3.8 부터 새로 추가된 기능이라는데, Assignment Expression 이라는게 있다. 말 그대로, 새로운 할당법이다. 선할당, 후검토랄까.

다음 코드를 보자.

fresh_fruit = {
    'apple': 10,
    'banana': 8,
    'lemon': 5,
}

count = fresh_fruit.get('lemon', 0)
if count:
    make_lemonade(count)
else:
    out_of_stock()

별 게 없는데, Effective Python 의 저자는 이 코드를 ‘It is noisier than it needs to be.’ 라고 표현했다. 그 이유는 count 가 굉장히 중요하게 보이는 듯이 if 문 위에 정의돼있지만, 실제로는 if 문에서 딱 한번 쓰이고 말기 때문이다. 이게 뭐 그리 대단한 내용인지는 모르겠으나.. 보다 더 이해하기 쉬운 예는 뒤에 나온다.

어쨌든, 여기서 count 가 하는 역할은 이렇다.

  • 값을 가져온다.
  • 그 값이 0 이 아닌지 확인한다.
  • 그리고 값을 활용한다.

이런 작업은 Python 내에서 계속 반복된다고 한다. 따라서, 이것을 조금이라도 명확하게, 짧게 줄일 수 있다면 코드 가독성(Readability)에 큰 도움을 줄 수 있기에, 그런 맥락에서 Assignment Expression 이 나왔다.

if count := fresh_fruit.get('lemon', 0):
    make_lemonade(count)
else:
    out_of_stock()

할당, 그리고 활용이 한 줄에 이뤄졌다. 먼저 count 에 값을 할당한 후, count 를 활용(if)한다.

이처럼, 콜론과 등호(:=)를 한 쌍으로 Assign Expression 이 이뤄지고, 이걸 Walrus Operator 라고 부른다. Walrus 는 ‘바다 코끼리’라는데, 사전 사진에 있는 눈동자와 긴 이빨이 := 와 꼭 닮았다.

이제 두번째 예제. 첫번째보다는 좀 더 쓸만하다.

Python 에는 switch/case 가 없기 때문에, 이 기능을 주로 if 로 구현한다. Dict.를 쓰기도 하지만서도.

count = fresh_fruit.get('banana', 0)
if count >= 2:
    pieces = slice_bananas(count)
    to_enjoy = make_smoothies(pieces)
else:
    count = fresh_fruit.get('apple', 0)
    if count >= 4:
        to_enjoy = make_cider(count)
    else:
        count = fresh_fruit.get('lemon', 0)
        if count:
            to_enjoy = make_lemonade(count)
        else:
            to_enjoy = 'Nothing'

이런 식으로 if 로만 구현을 하다보니, 눈에 잘 들어오지도 않고, 들여쓰기가 계속 되어 논리의 흐름이 끊기며, count 할당이 중복되기도 하여 종합하면 좀 저렴한(?) 티가 난다.
이걸 신문물로 치장하면 이렇게 된다.

if (count := fresh_fruit.get('banana', 0)) >= 2:
    pieces = slice_bananas(count)
    to_enjoy = make_smoothies(pieces)
elif (count := fresh_fruit.get('apple', 0)) >= 4:
    to_enjoy = make_cider(count)
elif count := fresh_fruit.get('lemon', 0):
    to_enjoy = make_lemonade(count)
else:
    to_enjoy = 'Nothing'

확 짧아지고, 일목요연해졌다. 이 정도면 switch/case 라 해도 손색이 없다.
다음에 코딩할 때 잊지 말고 꼭 써봐야겠다.

혹시나 해서 덧붙이지만, 저기서 콜론을 빼면 당연히 오류(SyntaxError: invalid syntax)가 발생한다.
또, Python 3.7 이하에서는 아예 안된다. (아마도?)

배운 걸 잊지 않기 위해 이렇게 기록까지 해 뒀는데, 며칠 뒤에 Walrus 가 뭐였지..??? 하는 서글픔은 찾아오지 않기를.

아무도안아무도안
Author: 아무도안

안녕하세요. 글 남겨주셔서 고맙습니다.