반응형

* 본 게시물은 하기 링크의 원문을 참고하였습니다.

https://docs.python.org/3.9/whatsnew/3.9.html
martinheinz.dev/blog/21

1. 파이썬 3.9 버전

파이썬 3.9는 아직 정식 릴리즈 버전이 아닌 베타 버전입니다. ( 2020.05.30 기준 최신 릴리즈 : 3.9.0b1)

따라서 공식문서도 아직 초안 형식이기 때문에 본 게시물은 향후 진행되는 업데이트 내용에 따라 달라질 수 있습니다.

2. 파이썬 3.9에서 달라지는 점들

1. 새로운 Dictionary 연산자

dictionary 간 병합에 사용되는 새로운 연산자가 추가되었습니다. 기존에 dictionary를 병합하기 위해 아래와 같은 3가지 방법 중 선택해야 했습니다.

# Sample dictionaries :
d1 = {"x": 1, "y": 4, "z": 10}
d2 = {"a": 7, "b": 9, "x": 5}

# Expected output after merging
{'x': 5, 'y': 4, 'z': 10, 'a': 7, 'b': 9}
# Notice that "x" got overridden by value from second dictionary

# 1. Option
d = dict(d1, **d2)

# 2. Option
d = d1.copy()  # Copy the first dictionary
d.update(d2)   # Update it "in-place" with second one

# 3. Option
d = {**d1, **d2}

첫 번째 방법은 dict(iter, **kwargs)로 사전을 재구성하는 방식입니다. 첫 번째 인수로 dict type 데이터가 들어가고, 2번째 인수로 '해체된 dict' 즉 key: value 형태로 구성된 list type입니다.
두 번째 방법은 copy-update를 통해 새로운 dict을 형성하는 방법입니다.
세 번째는 가장 clean 한 방식으로 병합하고자 하는 모든 dict을 해체된 dict형태로 만든 다음 새로운 dict을 구성하는 방법입니다.

이제 python 3.9 버전으로 넘어오면서 새로운 방법을 제공합니다.

# Normal merging
d = d1 | d2
# d = {'x': 5, 'y': 4, 'z': 10, 'a': 7, 'b': 9}

# In-place merging
d1 |= d2
# d1 = {'x': 5, 'y': 4, 'z': 10, 'a': 7, 'b': 9}

첫 번째 방법은 | 연산자를 통해 두 dict를 합한 새로운 dict을 만드는 방식으로 기존에 사용하던 첫 번째 방식과 유사합니다.
두 번째 방법은 no copy - update로 기존 dict을 업데이트하는 방식으로 두번째 방식과 유사합니다.

2. 유형 주석 업데이트

이제 list와 dict 같은 타입 유형을 지정하여 사용하기 용이해졌습니다.

def greet_all(names: list[str]) -> None:
    for name in names:
        print("Hello", name)

3. Module update

1. math

math 모듈의 gcd(최대공약수 계산) 기능이 강화되고 lcm(최소공배수), nextafter(가장 근사한 부동 소수점 값 계산), ulp(부동 소수점의 가장 하위단 출력) 기능이 추가되었습니다.

import math

# Greatest common divisor
math.gcd(80, 64, 152)
# result : 8

# Least common multiple
math.lcm(4, 8, 5)
# result : 40

# Next float after 4 going towards 5
math.nextafter(4, 5)
# result : 4.000000000000001
# Next float after 9 going towards 0
math.nextafter(9, 0)
# result : 8.999999999999998

# Unit in the Last Place
math.ulp(1000000000000000)
#result : 0.125

math.ulp(3.14159265)
#result : 4.440892098500626e-16

기존 math의 gcd 함수는 2개의 인수만 지원했으나, 이제 더욱 많은 수의 인수를 지원합니다.
새로 생긴 lcm은 최소공배수를 반환합니다.
새로 생긴 nextafter(x, y)는 x -> y로 향할 때 x에 가장 근접한 부동소수점 단위 숫자를 반환합니다.
새로 생긴 ulp는 '마지막 장소 단위'로 계산의 정밀도를 평가하는 데 사용할 수 있습니다.
(가령 pi = 3.14159... 의 값을 갖지만 우리가 표현할 수 있는 한계가 3.14라면 우리가 보는 값은 실제와 0.00159... 의 차이가 있으며, 다양한 경우에서 이러한 차이는 실수값으로도 나타날 수 있습니다.) 해당 내용에 대한 자세한 설명이 궁금하신 분들은 https://matthew-brett.github.io/teaching/floating_error.html 링크를 참고하시면 좋을 것 같습니다.

2. str

접두사와 접미사를 제거하는 새로운 함수가 추가되었습니다.

# Remove prefix
"someText".removeprefix("some")
#result : "Text"

# Remove suffix
"someText".removesuffix("Text")
#result : "some"

위 두 함수는 string[len(prefix):] 또는 string[:len(suffix)] 로도 수행할 수 있지만 조금 더 직관적이고, 원치 않는 제거를 방지할 수 있다는 점에서 유용한 기능이 될 것입니다.

3. http, ipaddress 지원

http status code 몇 가지가 추가되었습니다.
또한 이제 ipaddress에서 IPv6Address가 추가되어 ipv6 주소를 지원합니다.

4. functools

이제 functools 모듈에서 topological sort를 지원합니다. 토폴로지 정렬은 여러 알고리즘 문제에서도 자주 등장하는 문제인데 이제 python 3.9부터는 별도의 구성없이 내장 함수로 계산이 가능해졌습니다.

from functools import TopologicalSorter
graph = {"A": {"D"}, "B": {"D"}, "C": {"E", "H"}, "D": {"F", "G", "H"}, "E": {"G"}}
ts = TopologicalSorter(graph)
list(ts.static_order())
#result : ['H', 'F', 'G', 'D', 'E', 'A', 'B', 'C']

5. os

os 모듈에 CLD_KILLEd, CLD_STOPPED 클래스가 추가되었습니다. 이제 자식 프로세스(child proccess)를 끝내거나 중지시키는 게 가능합니다.
또한 unsetenv()가 윈도우에서도 동작합니다.

6. xml

xml.etree.ElementTree 를 통해 XML 파일로 직렬화 할 때 이제 공백이 유지됩니다.

3. 정리

확실히 버전업에 가까운 업데이트라 편의성 위주의 강화가 눈에 띕니다. 또한 토폴로지 정렬이 지원된다는 점은 굉장히 인상적인 것 같습니다. 다만 아직 정식 출시 버전이 아닌 만큼 안전성에 문제가 있을 수 있고 얼마든지 변경될 수 있기 때문에 바로 사용하기보단 정식버전을 기다리시는 게 좋을 것 같습니다. 정식버전 출시가 언제가 될지는 모르겠지만, 업데이트 방향성과 속도를 볼 때 3.8 업데이트보다 기대해볼 만해 보입니다.

반응형
복사했습니다!