6월 4일에는 Python 3.8.0b1이, 7월 4일에는 두 번째 베타 버전인 Python 3.8.0b2가 릴리즈됐다. 이는 Python 3.8이 feature complete하게 되었다는 것을 의미한다. 정식 릴리즈가 10월에 이뤄질텐데, 그 전에 이 베타 버전을 통해 Python 3.8의 새로운 기능들을 살펴보자. 이해하기 쉽고 headline이라고 볼 수 있는 변경 사항들만 언급할테니, 외의 내용들은 파이썬 공식 문서를 읽어보기 바란다.

Walrus Operator

Assignment Expression이라는 이름으로 PEP 572에 소개된 walrus operator 개념이 포함되었다. NAME := expr이라는 표기법을 사용하여 변수 할당을 할 수 있게 만드는 것이다. condition capturing이라는 어휘로 이해하면 될 것 같다.

이는 if statement의 entry point 레벨에서, 해당 block scope에 대한 변수를 정의할 때 사용할 수 있다.

if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

그리고 while statement에서 iteration마다의 변수 할당에 사용할 수 있다. 이는 디테일한 iteration을 구현할 때 매우 많은 도움이 된다. 예를 들어 파일의 내용을 순서대로 16바이트씩 읽어 처리하는 모종의 스크립트를 작성한다고 하면, Python 3.8은 walrus operator 덕분에 더 간결하고 깔끔해 진다.

f = open('...')

while chunk := f.read(16):
    ...

comprehension에서도 사용할 수 있다. 위에서도 말했듯 condition capturing이라는 어휘로 이해하자.

def f(x):
    ...

results = [(x, y, x/y) for x in input_data if (y := f(x)) > 0]

응용한다고 쳤을 때, 대화형 CLI 어플리케이션이나 socket 관련 어플리케이션을 만들 때 사용할 수도 있겠다.

while (command := input("> ")) != "quit":
    print(f"You entered: {command}")


while data := sock.recv(8192):
    print(f"Received data: {data}")

Debug support for f-strings

타이틀만 봤을 땐 fstring이 디버깅 관련 문제가 있어서 이걸 개선했겠거니 싶었는데, fstring에 대한 문법이 추가된 것이었다. 바로 = specifier다. f'{expr=}' 식으로 작성된 섹션은, 해당 표현식 그대로의 텍스트와, 평가된 표현식의 순서대로 문자열이 된다.

x = 3
print(f'{x=}')  # x=3
print(f'{x*3=}')  # x*3=9
print(f'{x * 9 + 15 = }')  # x * 9 + 15 = 42

예제에도 포함되어 있듯이, expression에 들어 있는 공백이 보존되기 때문에 매우 유용하다.

Positional-only parameters

keyword-only parameter를 위해 * specifier가 지원되고 있었는데, Python 3.8에서는 positional-only parameter 개념이 생겨나며 함수에 / specifier가 새로이 지원된다. PEP 570에 이 내용이 명시되어 있으며, 따라서 Python 3.8부터는 파라미터를 positional-only, positional-or-keyword, keyword-only로 나누어야 한다.

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      -----------    ----------     ----------
        |             |                  |
        |        Positional or keyword   |
        |                                - Keyword only
         -- Positional only