๐Ÿ ํŒŒ์ด์ฌ 3.9/3.10/3.11์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ํƒ์ƒ‰ ๐Ÿš€

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿ ํŒŒ์ด์ฌ 3.9/3.10/3.11์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ํƒ์ƒ‰ ๐Ÿš€

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, ํŒŒ์ด์ฌ ๋•ํ›„ ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ ํŒŒ์ด์ฌ์˜ ์ตœ์‹  ๋ฒ„์ „๋“ค์— ๋Œ€ํ•ด ๊นŠ์ด ํŒŒํ—ค์ณ๋ณผ ๊ฑฐ์˜ˆ์š”. 3.9๋ถ€ํ„ฐ 3.11๊นŒ์ง€, ํŒŒ์ด์ฌ์ด ์–ด๋–ป๊ฒŒ ์ง„ํ™”ํ–ˆ๋Š”์ง€ ํ•จ๊ป˜ ์•Œ์•„๋ณด์ฃ . ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹ค๋ ฅ์„ ๋ฝ๋‚ด๊ณ  ์‹ถ์€ ๋ถ„๋“ค์ด๋ผ๋ฉด ์ฃผ๋ชฉ! ์ด ๊ธ€์„ ์ฝ๊ณ  ๋‚˜๋ฉด ์—ฌ๋Ÿฌ๋ถ„๋„ ํŒŒ์ด์ฌ ๊ณ ์ˆ˜๊ฐ€ ๋  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ใ…‹ใ…‹ใ…‹

๐Ÿ’ก Tip: ํŒŒ์ด์ฌ์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ์ตํžˆ๋ฉด, ์žฌ๋Šฅ๋„ท์—์„œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋”ฉ ์‹ค๋ ฅ์„ ๋”์šฑ ๋น›๋‚˜๊ฒŒ ๋ฝ๋‚ผ ์ˆ˜ ์žˆ์–ด์š”!

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ์š”? ํŒŒ์ด์ฌ์˜ ์„ธ๊ณ„๋กœ ํ’๋ฉ ๋น ์ ธ๋ด…์‹œ๋‹ค! ๐ŸŠโ€โ™‚๏ธ

๐ŸŽ‰ Python 3.9์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค

2020๋…„ 10์›”์— ์ถœ์‹œ๋œ ํŒŒ์ด์ฌ 3.9๋Š” ์ •๋ง ๋งŽ์€ ๊ฐœ์„ ์‚ฌํ•ญ๊ณผ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ๊ฐ€์ ธ์™”์–ด์š”. ๋งˆ์น˜ ํฌ๋ฆฌ์Šค๋งˆ์Šค ์„ ๋ฌผ์„ ํ‘ธ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์„ค๋ ˆ๋Š” ๋งˆ์Œ์œผ๋กœ ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณผ๊นŒ์š”?

1. ๋”•์…”๋„ˆ๋ฆฌ ๋ณ‘ํ•ฉ ๋ฐ ์—…๋ฐ์ดํŠธ ์—ฐ์‚ฐ์ž (|, |=)

์ด์ œ ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ํ•ฉ์น  ๋•Œ ๋” ์ด์ƒ update() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋ผ์š”. ํŒŒ์ด์ฌ 3.9์—์„œ๋Š” ํŒŒ์ดํ”„(|) ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ์‰ฝ๊ฒŒ ๋ณ‘ํ•ฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์–ด์š”.


# ์ด์ „ ๋ฐฉ์‹
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
merged = {**dict1, **dict2}

# ์ƒˆ๋กœ์šด ๋ฐฉ์‹
merged = dict1 | dict2

์–ด๋•Œ์š”? ํ›จ์”ฌ ๊ฐ„๋‹จํ•ด ๋ณด์ด์ฃ ? ใ…‹ใ…‹ใ…‹ ์ด์ œ ๋”•์…”๋„ˆ๋ฆฌ ๋ณ‘ํ•ฉ์ด ๋งˆ์น˜ ๋‘ ๊ฐ•๋ฌผ์ด ๋งŒ๋‚˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ž์—ฐ์Šค๋Ÿฌ์›Œ์กŒ์–ด์š”! ๐ŸŒŠ

๐Ÿšจ ์ฃผ์˜: ๋‘ ๋”•์…”๋„ˆ๋ฆฌ์— ๊ฐ™์€ ํ‚ค๊ฐ€ ์žˆ๋‹ค๋ฉด, ์˜ค๋ฅธ์ชฝ ๋”•์…”๋„ˆ๋ฆฌ์˜ ๊ฐ’์ด ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์ ธ์š”. ๋งˆ์น˜ ๊ฐ€์œ„๋ฐ”์œ„๋ณด์—์„œ ํ•ญ์ƒ ์˜ค๋ฅธ์†์ด ์ด๊ธฐ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”!

2. ๋ฌธ์ž์—ด ๋ฉ”์„œ๋“œ์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ: removeprefix()์™€ removesuffix()

๋ฌธ์ž์—ด ๋‹ค๋ฃจ๋Š” ๊ฒŒ ์ด์ œ ๋” ์‰ฌ์›Œ์กŒ์–ด์š”! removeprefix()์™€ removesuffix() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ž์—ด์˜ ์•ž๋ถ€๋ถ„์ด๋‚˜ ๋’ท๋ถ€๋ถ„์„ ์†์‰ฝ๊ฒŒ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์ฃ .


text = "Hello, World!"
print(text.removeprefix("Hello, "))  # ์ถœ๋ ฅ: World!
print(text.removesuffix("!"))  # ์ถœ๋ ฅ: Hello, World

์ด ๊ธฐ๋Šฅ๋“ค ๋•๋ถ„์— ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ๊ฐ€ ํ›จ์”ฌ ๊ฐ„ํŽธํ•ด์กŒ์–ด์š”. ๋งˆ์น˜ ์ผ€์ดํฌ์˜ ์žฅ์‹์„ ๋–ผ์–ด๋‚ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์‰ฝ์ฃ ? ๐Ÿฐ

3. ํƒ€์ž… ํžŒํŠธ์˜ ๊ฐœ์„ 

ํŒŒ์ด์ฌ 3.9์—์„œ๋Š” ํƒ€์ž… ํžŒํŠธ๋ฅผ ๋”์šฑ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์–ด์š”. ์ด์ œ typing ๋ชจ๋“ˆ์„ importํ•˜์ง€ ์•Š๊ณ ๋„ ๋‚ด์žฅ ์ปฌ๋ ‰์…˜ ํƒ€์ž…์„ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.


# ์ด์ „ ๋ฐฉ์‹
from typing import List, Dict

def process_items(items: List[str]) -> Dict[str, int]:
    ...

# ์ƒˆ๋กœ์šด ๋ฐฉ์‹
def process_items(items: list[str]) -> dict[str, int]:
    ...

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๋” ๊น”๋”ํ•ด์ง€๊ณ , ๊ฐ€๋…์„ฑ๋„ ์ข‹์•„์ง€์ฃ . ๋งˆ์น˜ ๋ณต์žกํ•œ ์ˆ˜์‹์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌํ•œ ๊ฒƒ ๊ฐ™์•„์š”! ๐Ÿ‘จโ€๐Ÿซ

4. ์ƒˆ๋กœ์šด ํŒŒ์„œ

ํŒŒ์ด์ฌ 3.9์—์„œ๋Š” ์ƒˆ๋กœ์šด ํŒŒ์„œ(PEG ํŒŒ์„œ)๋ฅผ ๋„์ž…ํ–ˆ์–ด์š”. ์ด ํŒŒ์„œ๋Š” ์ด์ „์˜ LL(1) ํŒŒ์„œ๋ณด๋‹ค ๋” ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•ด์š”. ๋•๋ถ„์— ๋ฌธ๋ฒ•์˜ ๋ชจํ˜ธ์„ฑ์„ ๋” ์ž˜ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์ฃ .

์ด ๋ณ€ํ™”๋Š” ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ๋Š” ํฌ๊ฒŒ ์™€๋‹ฟ์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์–ธ์–ด ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ๋Š” ์ •๋ง ํฐ ๋ณ€ํ™”์˜ˆ์š”. ๋งˆ์น˜ ์ž๋™์ฐจ์˜ ์—”์ง„์„ ์™„์ „ํžˆ ์ƒˆ๊ฒƒ์œผ๋กœ ๋ฐ”๊พผ ๊ฒƒ๊ณผ ๊ฐ™์ฃ ! ๐Ÿš—๐Ÿ’จ

5. ์‹œ๊ฐ„ ์ธก์ • ํ•จ์ˆ˜์˜ ๊ฐœ์„ 

time.monotonic()๊ณผ time.perf_counter() ํ•จ์ˆ˜๊ฐ€ ์ด์ œ ๋‚˜๋…ธ์ดˆ ๋‹จ์œ„์˜ ์ •๋ฐ€๋„๋ฅผ ์ œ๊ณตํ•ด์š”. ์ด์ „์—๋Š” ๋งˆ์ดํฌ๋กœ์ดˆ๊นŒ์ง€๋งŒ ์ง€์›ํ–ˆ๋Š”๋ฐ, ์ด์ œ๋Š” ๋” ์ •๋ฐ€ํ•œ ์‹œ๊ฐ„ ์ธก์ •์ด ๊ฐ€๋Šฅํ•ด์กŒ์–ด์š”.


import time

start = time.perf_counter_ns()
# ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜๊ณ  ์‹ถ์€ ์ฝ”๋“œ
end = time.perf_counter_ns()

print(f"์‹คํ–‰ ์‹œ๊ฐ„: {end - start} ๋‚˜๋…ธ์ดˆ")

์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋น ๋ฅธ์ง€ ๋” ์ •ํ™•ํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์œก์ƒ ์„ ์ˆ˜์˜ ๊ธฐ๋ก์„ 1000๋ถ„์˜ 1์ดˆ๊นŒ์ง€ ์ธก์ •ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ •๋ฐ€ํ•˜์ฃ ! ๐Ÿƒโ€โ™‚๏ธโฑ๏ธ

6. zoneinfo ๋ชจ๋“ˆ ์ถ”๊ฐ€

์‹œ๊ฐ„๋Œ€ ์ฒ˜๋ฆฌ๊ฐ€ ๋” ์‰ฌ์›Œ์กŒ์–ด์š”! zoneinfo ๋ชจ๋“ˆ์ด ์ถ”๊ฐ€๋˜์–ด IANA ์‹œ๊ฐ„๋Œ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์ฃ .


from zoneinfo import ZoneInfo
from datetime import datetime

# ์„œ์šธ ์‹œ๊ฐ„
seoul_time = datetime.now(ZoneInfo("Asia/Seoul"))
print(f"์„œ์šธ ์‹œ๊ฐ„: {seoul_time}")

# ๋‰ด์š• ์‹œ๊ฐ„
ny_time = datetime.now(ZoneInfo("America/New_York"))
print(f"๋‰ด์š• ์‹œ๊ฐ„: {ny_time}")

์ด์ œ ์ „ ์„ธ๊ณ„ ์‹œ๊ฐ„์„ ๋‹ค๋ฃจ๋Š” ๊ฒŒ ํ›จ์”ฌ ์‰ฌ์›Œ์กŒ์–ด์š”. ๋งˆ์น˜ ์„ธ๊ณ„ ์‹œ๊ณ„๋ฅผ ์†๋ชฉ์— ์ฐจ๊ณ  ๋‹ค๋‹ˆ๋Š” ๊ฒƒ ๊ฐ™์ฃ ? ๐ŸŒโŒš

7. ์ผ๋ฐ˜ ํ‘œํ˜„์‹

ํŒŒ์ด์ฌ 3.9์—์„œ๋Š” ์ผ๋ฐ˜ ํ‘œํ˜„์‹(Generic Expression)์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ๊ฐœ๋…์ด ๋„์ž…๋์–ด์š”. ์ด๋ฅผ ํ†ตํ•ด ํƒ€์ž… ํžŒํŠธ๋ฅผ ๋”์šฑ ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์ฃ .


from typing import Generic, TypeVar

T = TypeVar('T')

class Stack(Generic[T]):
    def __init__(self):
        self.items: list[T] = []

    def push(self, item: T) -> None:
        self.items.append(item)

    def pop(self) -> T:
        return self.items.pop()

# ๋ฌธ์ž์—ด ์Šคํƒ
string_stack = Stack[str]()
string_stack.push("Hello")
string_stack.push("World")

# ์ •์ˆ˜ ์Šคํƒ
int_stack = Stack[int]()
int_stack.push(1)
int_stack.push(2)

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‹ค์–‘ํ•œ ํƒ€์ž…์˜ ์Šคํƒ์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋ ˆ๊ณ  ๋ธ”๋ก์ฒ˜๋Ÿผ ์›ํ•˜๋Š” ๋Œ€๋กœ ์กฐ๋ฆฝํ•  ์ˆ˜ ์žˆ์ฃ ! ๐Ÿงฑ

8. ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ ๊ฐœ์„ 

ํŒŒ์ด์ฌ 3.9์—์„œ๋Š” ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ ๋ชจ๋“ˆ์ด ๊ฐœ์„ ๋˜์—ˆ์–ด์š”. ํŠนํžˆ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์ด ๋” ํšจ์œจ์ ์œผ๋กœ ๋ณ€๊ฒฝ๋์ฃ .


from multiprocessing import shared_memory

# ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์ƒ์„ฑ
shm = shared_memory.SharedMemory(create=True, size=10)

# ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ์ดํ„ฐ ์“ฐ๊ธฐ
shm.buf[:] = b'Hello'

# ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์—์„œ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ
existing_shm = shared_memory.SharedMemory(name=shm.name)
print(bytes(existing_shm.buf[:5]))  # ์ถœ๋ ฅ: b'Hello'

# ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ
shm.close()
shm.unlink()

์ด์ œ ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ๋” ํšจ์œจ์ ์œผ๋กœ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ํ•˜๋‚˜์˜ ์น ํŒ์„ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ ! ๐Ÿ‘ฅ๐Ÿ–Š๏ธ

๐Ÿ’ก Tip: ์žฌ๋Šฅ๋„ท์—์„œ ํŒŒ์ด์ฌ 3.9์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ํ™œ์šฉํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ณต์œ ํ•ด๋ณด์„ธ์š”. ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์˜ ๊ด€์‹ฌ์„ ๋Œ ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”!

ํŒŒ์ด์ฌ 3.9์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค, ์–ด๋– ์‹ ๊ฐ€์š”? ์ •๋ง ๋งŽ์€ ๊ฐœ์„ ์‚ฌํ•ญ๋“ค์ด ์žˆ์ฃ ? ์ด์ œ 3.10์œผ๋กœ ๋„˜์–ด๊ฐ€๋ณผ๊นŒ์š”? ๋” ํฅ๋ฏธ์ง„์ง„ํ•œ ๊ธฐ๋Šฅ๋“ค์ด ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์–ด์š”! ๐ŸŽข

๐Ÿš€ Python 3.10์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค

2021๋…„ 10์›”์— ์ถœ์‹œ๋œ ํŒŒ์ด์ฌ 3.10์€ ์ •๋ง ๋งŽ์€ ๊ธฐ๋Œ€๋ฅผ ๋ฐ›์•˜์–ด์š”. ๊ทธ๋งŒํผ ์ƒˆ๋กญ๊ณ  ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ๋“ค์ด ์ถ”๊ฐ€๋๊ฑฐ๋“ ์š”. ๋งˆ์น˜ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ๊ธฐ๋‹ค๋ฆฌ๋˜ ์˜ํ™”์˜ ์†ํŽธ์„ ๋ณด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์„ค๋ ˆ๋Š” ๋งˆ์Œ์œผ๋กœ ์‚ดํŽด๋ณผ๊นŒ์š”? ๐Ÿฟ

1. ๊ตฌ์กฐ์  ํŒจํ„ด ๋งค์นญ (Structural Pattern Matching)

ํŒŒ์ด์ฌ 3.10์˜ ๊ฐ€์žฅ ํฐ ๋ณ€ํ™”๋Š” ๋ฐ”๋กœ ๊ตฌ์กฐ์  ํŒจํ„ด ๋งค์นญ์ด์—์š”. ์ด ๊ธฐ๋Šฅ์€ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์˜ switch-case ๋ฌธ๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ, ํ›จ์”ฌ ๋” ๊ฐ•๋ ฅํ•˜๊ณ  ์œ ์—ฐํ•ด์š”.


def analyze_type(data):
    match data:
        case []:
            print("๋นˆ ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.")
        case [x]:
            print(f"ํ•˜๋‚˜์˜ ์š”์†Œ {x}๋ฅผ ๊ฐ€์ง„ ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.")
        case [x, y]:
            print(f"๋‘ ๊ฐœ์˜ ์š”์†Œ {x}์™€ {y}๋ฅผ ๊ฐ€์ง„ ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.")
        case [x, y, *rest]:
            print(f"์ฒซ ๋‘ ์š”์†Œ๋Š” {x}์™€ {y}์ด๊ณ , ๋‚˜๋จธ์ง€๋Š” {rest}์ž…๋‹ˆ๋‹ค.")
        case {'name': name, 'age': age}:
            print(f"{name}์€(๋Š”) {age}์‚ด์ž…๋‹ˆ๋‹ค.")
        case _:
            print("์•Œ ์ˆ˜ ์—†๋Š” ๋ฐ์ดํ„ฐ ํ˜•์‹์ž…๋‹ˆ๋‹ค.")

analyze_type([1, 2, 3, 4, 5])
analyze_type({'name': 'ํŒŒ์ด์ฌ', 'age': 30})

์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ณต์žกํ•œ if-elif ๊ตฌ๋ฌธ์„ ํ›จ์”ฌ ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ํผ์ฆ ์กฐ๊ฐ์„ ๋งž์ถ”๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์กฐ๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์ฃ ! ๐Ÿงฉ

๐ŸŒŸ ๊ฟ€ํŒ: ๊ตฌ์กฐ์  ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋ผ์š”. ํŠนํžˆ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์ง„๊ฐ€๋ฅผ ๋ฐœํœ˜ํ•˜์ฃ !

2. ๋” ์ •ํ™•ํ•œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€

ํŒŒ์ด์ฌ 3.10์—์„œ๋Š” ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋”์šฑ ์ƒ์„ธํ•ด์ง€๊ณ  ์ •ํ™•ํ•ด์กŒ์–ด์š”. ํŠนํžˆ ๊ตฌ๋ฌธ ์˜ค๋ฅ˜(SyntaxError)์— ๋Œ€ํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ํฌ๊ฒŒ ๊ฐœ์„ ๋์ฃ .


# ํŒŒ์ด์ฌ 3.9 ์ด์ „
if True
    print("Hello")
# SyntaxError: invalid syntax

# ํŒŒ์ด์ฌ 3.10
if True
    print("Hello")
# SyntaxError: expected ':'

์ด์ œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋” ์ •ํ™•ํžˆ ์–ด๋””๊ฐ€ ์ž˜๋ชป๋๋Š”์ง€ ์•Œ๋ ค์ค˜์š”. ๋งˆ์น˜ ์นœ์ ˆํ•œ ์„ ์ƒ๋‹˜์ด ์ˆ™์ œ๋ฅผ ๋ด์ฃผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ ! ๐Ÿ‘จโ€๐Ÿซโœ…

3. ์ƒˆ๋กœ์šด ํƒ€์ž… ์œ ๋‹ˆ์˜จ ์—ฐ์‚ฐ์ž (|)

ํƒ€์ž… ํžŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ์—ฌ๋Ÿฌ ํƒ€์ž…์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ด์ œ ํŒŒ์ดํ”„(|) ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.


def greet(name: str | None) -> str:
    if name is None:
        return "Hello, Guest!"
    return f"Hello, {name}!"

print(greet("Alice"))  # ์ถœ๋ ฅ: Hello, Alice!
print(greet(None))     # ์ถœ๋ ฅ: Hello, Guest!

์ด์ „์—๋Š” Union[str, None]๊ณผ ๊ฐ™์ด ์จ์•ผ ํ–ˆ๋Š”๋ฐ, ์ด์ œ๋Š” ํ›จ์”ฌ ๊ฐ„๋‹จํ•ด์กŒ์–ด์š”. ๋งˆ์น˜ ํƒ€์ดํ•‘ํ•  ๋•Œ ์ˆจ์„ ๋œ ์‰ฌ์–ด๋„ ๋˜๋Š” ๊ฒƒ ๊ฐ™์ฃ ? ๐Ÿ˜ฎโ€๐Ÿ’จ

4. ์ปจํ…์ŠคํŠธ ๋งค๋‹ˆ์ €์—์„œ์˜ ๊ด„ํ˜ธ ์ƒ๋žต

์ด์ œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ปจํ…์ŠคํŠธ ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ด„ํ˜ธ๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์–ด์š”.


# ์ด์ „ ๋ฐฉ์‹
with (open('file1.txt', 'r') as f1,
      open('file2.txt', 'w') as f2):
    f2.write(f1.read())

# ์ƒˆ๋กœ์šด ๋ฐฉ์‹
with open('file1.txt', 'r') as f1, \
     open('file2.txt', 'w') as f2:
    f2.write(f1.read())

์ฝ”๋“œ๊ฐ€ ๋” ๊น”๋”ํ•ด ๋ณด์ด์ฃ ? ๋งˆ์น˜ ๋ถˆํ•„์š”ํ•œ ์žฅ์‹์„ ๋–ผ์–ด๋‚ธ ๊ฒƒ ๊ฐ™์•„์š”. ์‹ฌํ”Œ์ด์ฆˆ ๋” ๋ฒ ์ŠคํŠธ! ๐Ÿ‘Œ

5. ๋” ๊ฐ•๋ ฅํ•ด์ง„ ํƒ€์ž… ์ฒดํฌ

ํŒŒ์ด์ฌ 3.10์—์„œ๋Š” ํƒ€์ž… ์ฒดํฌ ๊ธฐ๋Šฅ์ด ๋”์šฑ ๊ฐ•ํ™”๋์–ด์š”. ํŠนํžˆ ์ œ๋„ค๋ฆญ ํƒ€์ž…์— ๋Œ€ํ•œ ์ง€์›์ด ๊ฐœ์„ ๋์ฃ .


from typing import Generic, TypeVar

T = TypeVar('T')

class Box(Generic[T]):
    def __init__(self, content: T):
        self.content = content

    def get_content(self) -> T:
        return self.content

int_box: Box[int] = Box(42)
str_box: Box[str] = Box("Hello")

print(int_box.get_content())  # ์ถœ๋ ฅ: 42
print(str_box.get_content())  # ์ถœ๋ ฅ: Hello

์ด์ œ ํƒ€์ž… ํžŒํŠธ๋ฅผ ๋” ์ •ํ™•ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋ ˆ๊ณ  ๋ธ”๋ก์˜ ๋ชจ์–‘์„ ๋” ์ •ํ™•ํ•˜๊ฒŒ ๋งž์ถœ ์ˆ˜ ์žˆ๊ฒŒ ๋œ ๊ฒƒ ๊ฐ™์ฃ ? ๐Ÿงฑโœจ

6. ์ƒˆ๋กœ์šด ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์–‘ ๋ฌธ๋ฒ•

ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ •์˜ํ•  ๋•Œ ์ƒˆ๋กœ์šด ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์–ด์š”.


def greet(name, /, *, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Alice", greeting="Hi"))  # ์ถœ๋ ฅ: Hi, Alice!
print(greet("Bob"))  # ์ถœ๋ ฅ: Hello, Bob!
# print(greet(name="Charlie"))  # ์˜ค๋ฅ˜: ์œ„์น˜ ์ „์šฉ ์ธ์ž์— ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ

์—ฌ๊ธฐ์„œ /๋Š” ๊ทธ ์•ž์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์œ„์น˜ ์ „์šฉ ์ธ์ž์ž„์„, *๋Š” ๊ทธ ๋’ค์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ํ‚ค์›Œ๋“œ ์ „์šฉ ์ธ์ž์ž„์„ ๋‚˜ํƒ€๋‚ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ฐฉ์‹์„ ๋” ์—„๊ฒฉํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์ฃ . ๋งˆ์น˜ ํŒŒํ‹ฐ์—์„œ ๋“œ๋ ˆ์Šค ์ฝ”๋“œ๋ฅผ ์ •ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿ‘—๐Ÿ•ด๏ธ

7. zip() ํ•จ์ˆ˜์˜ ๊ฐœ์„ 

zip() ํ•จ์ˆ˜์— ์ƒˆ๋กœ์šด strict ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋์–ด์š”. ์ด๋ฅผ ํ†ตํ•ด ๊ธธ์ด๊ฐ€ ๋‹ค๋ฅธ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ zipํ•  ๋•Œ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋์ฃ .


numbers = [1, 2, 3]
letters = ['a', 'b', 'c', 'd']

# ๊ธฐ์กด ๋ฐฉ์‹ (๊ธธ์ด๊ฐ€ ๋‹ค๋ฅด๋ฉด ์งง์€ ์ชฝ์— ๋งž์ถฐ์ง)
print(list(zip(numbers, letters)))  # ์ถœ๋ ฅ: [(1, 'a'), (2, 'b'), (3, 'c')]

# ์ƒˆ๋กœ์šด ๋ฐฉ์‹ (strict=True)
try:
    print(list(zip(numbers, letters, strict=True)))
except ValueError as e:
    print(f"์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")  # ์ถœ๋ ฅ: ์˜ค๋ฅ˜ ๋ฐœ์ƒ: zip() argument 2 is longer than argument 1

์ด์ œ ๋ฐ์ดํ„ฐ๋ฅผ zipํ•  ๋•Œ ์‹ค์ˆ˜๋กœ ๊ธธ์ด๊ฐ€ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์ง€ํผ๋ฅผ ์ž ๊ธ€ ๋•Œ ํ•œ ์ชฝ์ด ๋” ๊ธธ๋ฉด ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ฃ ! ๐Ÿค

8. ๋” ๋‚˜์€ ํƒ€์ž… ์ถ”๋ก 

ํŒŒ์ด์ฌ 3.10์—์„œ๋Š” ํƒ€์ž… ์ถ”๋ก  ๊ธฐ๋Šฅ์ด ๋”์šฑ ๊ฐœ์„ ๋์–ด์š”. ํŠนํžˆ ์ œ๋„ค๋ฆญ ํƒ€์ž…๊ณผ ๊ด€๋ จ๋œ ์ถ”๋ก ์ด ๊ฐ•ํ™”๋์ฃ .


from typing import TypeVar, Generic

T = TypeVar('T')

class Container(Generic[T]):
    def __init__(self, item: T):
        self.item = item

def process(container: Container[T]) -> T:
    return container.item

result = process(Container("Hello"))
print(result)  # ์ถœ๋ ฅ: Hello
print(type(result))  # ์ถœ๋ ฅ: <class>
</class>

์ด์ œ ํƒ€์ž… ์ฒด์ปค๊ฐ€ ๋” ์ •ํ™•ํ•˜๊ฒŒ ํƒ€์ž…์„ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์…œ๋ก ํ™ˆ์ฆˆ๊ฐ€ ๋” ๋˜‘๋˜‘ํ•ด์ง„ ๊ฒƒ ๊ฐ™์ฃ ? ๐Ÿ•ต๏ธโ€โ™‚๏ธ๐Ÿ”

๐Ÿ’ก Tip: ์žฌ๋Šฅ๋„ท์—์„œ ํŒŒ์ด์ฌ 3.10์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ํ™œ์šฉํ•œ ์ฝ”๋“œ ์˜ˆ์ œ๋ฅผ ๊ณต์œ ํ•ด๋ณด์„ธ์š”. ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ํฐ ๋„์›€์ด ๋  ๊ฑฐ์˜ˆ์š”!

ํŒŒ์ด์ฌ 3.10์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค, ์ •๋ง ๋Œ€๋‹จํ•˜์ฃ ? ์ด์ œ ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ๊ฐ€ ๋” ๊น”๋”ํ•˜๊ณ , ์•ˆ์ „ํ•˜๊ณ , ํšจ์œจ์ ์œผ๋กœ ๋ณ€ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋์ด ์•„๋‹ˆ์—์š”! ํŒŒ์ด์ฌ 3.11๋„ ์šฐ๋ฆฌ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋‹ต๋‹ˆ๋‹ค. ๋‹ค์Œ ์„น์…˜์—์„œ ๊ณ„์†ํ•ด์„œ ์•Œ์•„๋ณผ๊นŒ์š”? ๐Ÿš€

๐ŸŒŸ Python 3.11์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค

2022๋…„ 10์›”์— ์ถœ์‹œ๋œ ํŒŒ์ด์ฌ 3.11์€ ์ •๋ง ๋งŽ์€ ๊ธฐ๋Œ€๋ฅผ ๋ฐ›์•˜์–ด์š”. ํŠนํžˆ ์„ฑ๋Šฅ ๊ฐœ์„ ์— ํฐ ์ดˆ์ ์„ ๋งž์ท„๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, ๊ณผ์—ฐ ์–ด๋–ค ๋ณ€ํ™”๊ฐ€ ์žˆ์—ˆ์„๊นŒ์š”? ๋งˆ์น˜ ์Šˆํผ์นด์˜ ์ƒˆ ๋ชจ๋ธ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์„ค๋ ˆ๋Š” ๋งˆ์Œ์œผ๋กœ ์‚ดํŽด๋ณผ๊นŒ์š”? ๐ŸŽ๏ธ๐Ÿ’จ

1. ์„ฑ๋Šฅ ๊ฐœ์„ 

ํŒŒ์ด์ฌ 3.11์˜ ๊ฐ€์žฅ ํฐ ํŠน์ง•์€ ๋ฐ”๋กœ ์„ฑ๋Šฅ ๊ฐœ์„ ์ด์—์š”. ํ‰๊ท ์ ์œผ๋กœ 10-60% ์ •๋„ ๋นจ๋ผ์กŒ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, ์ด๋Š” ์ •๋ง ๋Œ€๋‹จํ•œ ๋ฐœ์ „์ด์ฃ !


import time

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

start = time.perf_counter()
result = fibonacci(30)
end = time.perf_counter()

print(f"๊ฒฐ๊ณผ: {result}")
print(f"์‹คํ–‰ ์‹œ๊ฐ„: {end - start:.4f}์ดˆ")

์ด ์ฝ”๋“œ๋ฅผ ํŒŒ์ด์ฌ 3.10๊ณผ 3.11์—์„œ ๊ฐ๊ฐ ์‹คํ–‰ํ•ด๋ณด๋ฉด, 3.11์—์„œ ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๊ฑฐ๋ถ์ด๊ฐ€ ํ† ๋ผ๋กœ ๋ณ€์‹ ํ•œ ๊ฒƒ ๊ฐ™์ฃ ? ๐Ÿขโžก๏ธ๐Ÿฐ

๐Ÿš€ ์†๋„ ์—…! ํŒŒ์ด์ฌ 3.11์˜ ์„ฑ๋Šฅ ๊ฐœ์„ ์œผ๋กœ ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ๊ทธ๋žจ์ด ๋” ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•  ๊ฑฐ์˜ˆ์š”. ์žฌ๋Šฅ๋„ท์—์„œ ๊ณต์œ ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋“ค๋„ ๋”์šฑ ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๊ฒ ์ฃ ?

2. ๋” ๋‚˜์€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€

ํŒŒ์ด์ฌ 3.11์—์„œ๋Š” ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋”์šฑ ์ƒ์„ธํ•ด์ง€๊ณ  ์œ ์šฉํ•ด์กŒ์–ด์š”. ํŠนํžˆ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์ •ํ™•ํ•œ ์œ„์น˜๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋์ฃ .


def divide(a, b):
    return a / b

try:
    result = divide(10, 0)
except ZeroDivisionError as e:
    print(f"์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
    print(f"์˜ค๋ฅ˜ ์œ„์น˜: {e.__traceback__.tb_lineno}๋ฒˆ ์ค„")

์ด์ œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ •ํ™•ํžˆ ์–ด๋Š ์ค„์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋Š”์ง€ ๋ฐ”๋กœ ์•Œ ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ GPS๊ฐ€ ์ •ํ™•ํ•œ ์œ„์น˜๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ ! ๐Ÿ—บ๏ธ๐Ÿ“

3. ์˜ˆ์™ธ ๊ทธ๋ฃน (Exception Groups)

ํŒŒ์ด์ฌ 3.11์—์„œ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์˜ˆ์™ธ๋ฅผ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ ๊ทธ๋ฃน ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋์–ด์š”.


def risky_operation(x):
    if x < 0:
        raise ValueError("์Œ์ˆ˜๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.")
    if x > 100:
        raise OverflowError("๋„ˆ๋ฌด ํฐ ์ˆซ์ž์ž…๋‹ˆ๋‹ค.")
    return 100 / x

try:
    risky_operation(-5)
    risky_operation(150)
    risky_operation(0)
except* ValueError as e:
    print(f"ValueError ๋ฐœ์ƒ: {e}")
except* OverflowError as e:
    print(f"OverflowError ๋ฐœ์ƒ: {e}")
except* ZeroDivision  Error as e:
    print(f"ZeroDivisionError ๋ฐœ์ƒ: {e}")

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ์˜ˆ์™ธ๋ฅผ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ๋™์‹œ์— ํ•ด๊ฒฐํ•˜๋Š” ์Šˆํผํžˆ์–ด๋กœ ๊ฐ™์ฃ ? ๐Ÿฆธโ€โ™‚๏ธ

4. ํƒ€์ž… ํžŒํŠธ ๊ฐœ์„ 

ํŒŒ์ด์ฌ 3.11์—์„œ๋Š” ํƒ€์ž… ํžŒํŠธ ๊ธฐ๋Šฅ์ด ๋”์šฑ ๊ฐ•ํ™”๋์–ด์š”. ํŠนํžˆ typing.Self ํƒ€์ž…์ด ์ถ”๊ฐ€๋˜์–ด ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ๋” ์ •ํ™•ํ•˜๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์ฃ .


from typing import Self

class ChainableList:
    def __init__(self, values: list[int]):
        self.values = values

    def append(self, value: int) -> Self:
        self.values.append(value)
        return self

    def extend(self, values: list[int]) -> Self:
        self.values.extend(values)
        return self

chain = ChainableList([1, 2, 3]).append(4).extend([5, 6])
print(chain.values)  # ์ถœ๋ ฅ: [1, 2, 3, 4, 5, 6]

์ด์ œ ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹์„ ์‚ฌ์šฉํ•  ๋•Œ ํƒ€์ž… ํžŒํŠธ๋ฅผ ๋” ์ •ํ™•ํ•˜๊ฒŒ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋„๋ฏธ๋…ธ๋ฅผ ๋” ์ •ํ™•ํ•˜๊ฒŒ ์„ธ์šธ ์ˆ˜ ์žˆ๊ฒŒ ๋œ ๊ฒƒ ๊ฐ™์ฃ ? ๐Ÿ€„

5. TOML ์ง€์›

ํŒŒ์ด์ฌ 3.11๋ถ€ํ„ฐ๋Š” TOML(Tom's Obvious, Minimal Language) ํŒŒ์ผ ํ˜•์‹์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•ด์š”. ์ด์ œ ๋ณต์žกํ•œ ์„ค์ • ํŒŒ์ผ์„ ๋” ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ๋์ฃ .


import tomllib

# config.toml ํŒŒ์ผ ๋‚ด์šฉ:
# [database]
# host = "localhost"
# port = 5432
# user = "admin"

with open("config.toml", "rb") as f:
    config = tomllib.load(f)

print(f"๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ˜ธ์ŠคํŠธ: {config['database']['host']}")
print(f"๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํฌํŠธ: {config['database']['port']}")

TOML ํŒŒ์ผ์€ ์ฝ๊ธฐ ์‰ฝ๊ณ  ์ž‘์„ฑํ•˜๊ธฐ ํŽธํ•ด์„œ, ํ”„๋กœ์ ํŠธ์˜ ์„ค์ •์„ ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ํ›จ์”ฌ ์ˆ˜์›”ํ•ด์กŒ์–ด์š”. ๋งˆ์น˜ ๋ณต์žกํ•œ ๋ ˆ์‹œํ”ผ๋ฅผ ๊ฐ„๋‹จํ•œ ์š”๋ฆฌ ์ฑ…์œผ๋กœ ์ •๋ฆฌํ•œ ๊ฒƒ ๊ฐ™์ฃ ? ๐Ÿ‘จโ€๐Ÿณ๐Ÿ“˜

6. ๋” ๋น ๋ฅธ ์‹œ์ž‘ ์‹œ๊ฐ„

ํŒŒ์ด์ฌ 3.11์—์„œ๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ์˜ ์‹œ์ž‘ ์‹œ๊ฐ„์ด ํฌ๊ฒŒ ๊ฐœ์„ ๋์–ด์š”. ํŠนํžˆ ๋งŽ์€ ๋ชจ๋“ˆ์„ importํ•˜๋Š” ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ๊ทธ ํšจ๊ณผ๊ฐ€ ๋‘๋“œ๋Ÿฌ์ง€์ฃ .


import time
import sys

start = time.perf_counter()
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
end = time.perf_counter()

print(f"๋ชจ๋“ˆ import ์‹œ๊ฐ„: {end - start:.4f}์ดˆ")
print(f"ํŒŒ์ด์ฌ ๋ฒ„์ „: {sys.version}")

์ด ์ฝ”๋“œ๋ฅผ ํŒŒ์ด์ฌ 3.10๊ณผ 3.11์—์„œ ๊ฐ๊ฐ ์‹คํ–‰ํ•ด๋ณด๋ฉด, 3.11์—์„œ ๋ชจ๋“ˆ import ์‹œ๊ฐ„์ด ํ›จ์”ฌ ์งง์•„์ง„ ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ํ„ฐ๋ณด ์—”์ง„์„ ๋‹จ ๊ฒƒ์ฒ˜๋Ÿผ ๋นจ๋ผ์กŒ์ฃ ! ๐Ÿš€

7. ํ–ฅ์ƒ๋œ ๋น„๋™๊ธฐ ์ž‘์—… ์ทจ์†Œ

ํŒŒ์ด์ฌ 3.11์—์„œ๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์„ ๋” ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์–ด์š”. ํŠนํžˆ asyncio.TaskGroup์ด ์ถ”๊ฐ€๋˜์–ด ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์‹คํ–‰ํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฌ์›Œ์กŒ์ฃ .


import asyncio

async def fetch_data(url):
    print(f"{url} ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๋Š” ์ค‘...")
    await asyncio.sleep(1)  # ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜
    print(f"{url} ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์™„๋ฃŒ!")
    return f"Data from {url}"

async def main():
    async with asyncio.TaskGroup() as tg:
        task1 = tg.create_task(fetch_data("https://api1.example.com"))
        task2 = tg.create_task(fetch_data("https://api2.example.com"))
        task3 = tg.create_task(fetch_data("https://api3.example.com"))

    results = [task1.result(), task2.result(), task3.result()]
    print(f"๋ชจ๋“  ๋ฐ์ดํ„ฐ: {results}")

asyncio.run(main())

์ด์ œ ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๋” ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ  ์ œ์–ดํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ ‘์‹œ๋ฅผ ๋™์‹œ์— ๋Œ๋ฆฌ๋Š” ์„œ์ปค์Šค ๊ณต์—ฐ์ฒ˜๋Ÿผ ๋ฉ‹์ง€์ฃ ? ๐ŸŽญ

8. ์ƒˆ๋กœ์šด ์‹œ๊ฐ„ ์กด API

ํŒŒ์ด์ฌ 3.11์—์„œ๋Š” zoneinfo ๋ชจ๋“ˆ์ด ๊ฐœ์„ ๋˜์–ด ์‹œ๊ฐ„๋Œ€ ์ฒ˜๋ฆฌ๊ฐ€ ๋”์šฑ ํŽธ๋ฆฌํ•ด์กŒ์–ด์š”.


from zoneinfo import ZoneInfo
from datetime import datetime, timedelta

seoul_time = datetime.now(ZoneInfo("Asia/Seoul"))
ny_time = datetime.now(ZoneInfo("America/New_York"))

print(f"์„œ์šธ ์‹œ๊ฐ„: {seoul_time}")
print(f"๋‰ด์š• ์‹œ๊ฐ„: {ny_time}")

# ์‹œ๊ฐ„๋Œ€ ๋ณ€ํ™˜
seoul_to_ny = seoul_time.astimezone(ZoneInfo("America/New_York"))
print(f"์„œ์šธ ์‹œ๊ฐ„์„ ๋‰ด์š• ์‹œ๊ฐ„์œผ๋กœ: {seoul_to_ny}")

์ด์ œ ์ „ ์„ธ๊ณ„ ์‹œ๊ฐ„์„ ๋” ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์ „ ์„ธ๊ณ„ ์‹œ๊ณ„๋ฅผ ํ•œ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ปจํŠธ๋กค ํƒ€์›Œ๋ฅผ ๊ฐ€์ง„ ๊ฒƒ ๊ฐ™์ฃ ? ๐ŸŒโฐ

๐Ÿ’ก Tip: ์žฌ๋Šฅ๋„ท์—์„œ ํŒŒ์ด์ฌ 3.11์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ํ™œ์šฉํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ณต์œ ํ•ด๋ณด์„ธ์š”. ํŠนํžˆ ์„ฑ๋Šฅ ๊ฐœ์„  ํšจ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ฒค์น˜๋งˆํฌ ๊ฒฐ๊ณผ๋Š” ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ํฐ ๋„์›€์ด ๋  ๊ฑฐ์˜ˆ์š”!

ํŒŒ์ด์ฌ 3.11์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค, ์ •๋ง ๋Œ€๋‹จํ•˜์ฃ ? ์ด์ œ ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ๊ฐ€ ๋” ๋น ๋ฅด๊ณ , ์•ˆ์ „ํ•˜๊ณ , ํšจ์œจ์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์–ด์š”. ์ด๋Ÿฌํ•œ ๋ณ€ํ™”๋“ค์€ ์šฐ๋ฆฌ๊ฐ€ ๋” ๋‚˜์€ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์ฃ . ๐ŸŒˆ

ํŒŒ์ด์ฌ 3.9๋ถ€ํ„ฐ 3.11๊นŒ์ง€์˜ ๋ณ€ํ™”๋ฅผ ์‚ดํŽด๋ณด๋ฉด, ํŒŒ์ด์ฌ์ด ์–ผ๋งˆ๋‚˜ ๋น ๋ฅด๊ฒŒ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์–ด์š”. ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋”ฉ ์‹ค๋ ฅ๋„ ํ•จ๊ป˜ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ์žฌ๋Šฅ๋„ท์—์„œ ์ด๋Ÿฐ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ํ™œ์šฉํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ณต์œ ํ•˜๋ฉด ์–ด๋–จ๊นŒ์š”? ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ์˜๊ฐ์„ ์ฃผ๊ณ , ํ•จ๊ป˜ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๊ธฐํšŒ๊ฐ€ ๋  ๊ฑฐ์˜ˆ์š”! ๐Ÿš€๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป

์ž, ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ ํŒŒ์ด์ฌ์˜ ์ตœ์‹  ๋ฒ„์ „๋“ค์— ๋Œ€ํ•ด ์ž˜ ์•Œ๊ฒŒ ๋์–ด์š”. ์ด ์ง€์‹์„ ํ™œ์šฉํ•ด์„œ ๋” ๋ฉ‹์ง„ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”. ํŒŒ์ด์ฌ์˜ ์„ธ๊ณ„๋Š” ๋์—†์ด ๋„“๊ณ  ๊นŠ๋‹ต๋‹ˆ๋‹ค. ๊ณ„์†ํ•ด์„œ ํƒํ—˜ํ•˜๊ณ  ๋ฐฐ์šฐ๋Š” ์ฆ๊ฑฐ์›€์„ ๋Š๊ปด๋ณด์„ธ์š”! ๐Ÿโœจ