Python ํ์ต ๊ฐ์ด๋
๋ฌธ๋ฒ, ํ๋ ์์ํฌ, ํจํค์ง โ ์ฝ๋ ๋ ๋ฒจ๋ก ๋์ ์๋ฆฌ ์ ๋ฆฌ
๐ ๋ฌธ๋ฒ & ๊ธฐ์ด
Generator์ yield โ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๋จน๋ ์ดํฐ๋ ์ด์ ์ ์๋ฆฌ
yield๊ฐ ํจ์ ์คํ์ "์ผ์ ์ ์ง"์ํค๋ ๋ฉ์ปค๋์ฆ
Generator๋ ๊ฐ์ ํ๊บผ๋ฒ์ ๋ง๋ค์ง ์๊ณ yield๋ก ํ๋์ฉ ๋ด๋ณด๋ธ๋ค. 10GB ํ์ผ์ ํ ์ค์ฉ ์ฒ๋ฆฌํ ์ ์๋ ์ด์ ๊ฐ ์ด๊ฒ์ด๋ค. ๋ด๋ถ์ ์ผ๋ก ํจ์์ ์คํ ํ๋ ์์ ๋ณด์กดํ๋ฉด์ ์คํ์ ์ค๋จ/์ฌ๊ฐํ๋ค.
Decorator ๋ด๋ถ ๊ตฌ์กฐ โ @๊ฐ ์ค์ ๋ก ํ๋ ์ผ
ํจ์๋ฅผ ๋ฐ์์ ํจ์๋ฅผ ๋ฐํํ๋ ํจ์ โ ๊ทธ๊ฒ ์ ๋ถ๋ค
@decorator๋ ๋ฌธ๋ฒ์ ์คํ(syntactic sugar)์ด๋ค. func = decorator(func)์ ๋์ผํ๋ค. ํด๋ก์ ์ *args/**kwargs ์กฐํฉ์ผ๋ก ์๋ณธ ํจ์๋ฅผ ๊ฐ์ธ๋ ํจํด.
Context Manager โ with๋ฌธ์ด ์ค์ ๋ก ํ๋ ์ผ
__enter__๊ณผ __exit__๋ก ๋ฆฌ์์ค ์ ๋ฆฌ๋ฅผ ๋ณด์ฅํ๋ ํ๋กํ ์ฝ
with open("f") as f: ์ with๋ __enter__()๋ฅผ ํธ์ถํด์ ๋ฆฌ์์ค๋ฅผ ์ป๊ณ , ๋ธ๋ก์ด ๋๋๋ฉด(์๋ฌ๊ฐ ๋๋ ์ ๋๋ ) __exit__()๋ก ์ ๋ฆฌํ๋ค. contextlib.contextmanager๋ก generator ๊ธฐ๋ฐ ๊ตฌํ๋ ๊ฐ๋ฅ.
Type Hints โ ๋ฐํ์์์๋ ์๋ฌด๊ฒ๋ ์ ํ๋ค
Python์ ํ์ ํํธ๊ฐ "ํํธ"์ธ ์ด์ ์, Pydantic์ด ์ด๊ฑธ ๊ทน๋ณตํ๋ ๋ฐฉ๋ฒ
Python์ type hint(: int, -> str)๋ ๋ฐํ์์ ๊ฒ์ฌ๋์ง ์๋๋ค. mypy ๊ฐ์ ์ ์ ๋ถ์ ๋๊ตฌ๊ฐ ์ฝ์ ๋ฟ์ด๋ค. Pydantic์ ์ด ํ๊ณ๋ฅผ __init_subclass__์ ๋ชจ๋ธ ๊ฒ์ฆ์ผ๋ก ๋์ด์์ ๋ฐํ์ ํ์ ๊ฒ์ฌ๋ฅผ ๊ตฌํํ๋ค.
Keyword-only ์ธ์ โ `*,` ๊ฐ ๋ญ์ง, ์ ์ฐ๋์ง
`def f(a, b, *, c)` ์ ๊ทธ ๋ณ ํ๋
Python์ `*,`๋ "์ฌ๊ธฐ๋ถํฐ๋ ํค์๋๋ก๋ง ๋ฐ๋๋ค"๋ ๊ตฌ๋ถ์ ์ด๋ค. ์์น ์ธ์๋ก ๋๊ธฐ๋ฉด TypeError. ํธ์ถ ์๋๋ฅผ ๋ช ํํ๊ฒ ํ๊ณ ์๊ทธ๋์ฒ ๋ณ๊ฒฝ์ ๊ฐํ๊ฒ ๋ง๋ ๋ค. Ruby์๋ `:` ํค์๋ ์ธ์ ์์ฒด๊ฐ ์ฒ์๋ถํฐ keyword-only๋ผ ๋ณ๋ ๋ฌธ๋ฒ์ด ํ์ ์๋ค.
โก FastAPI
FastAPI ์ํคํ ์ฒ โ Starlette + Pydantic + Uvicorn์ ์กฐํฉ
FastAPI๊ฐ "๋น ๋ฅด๋ค"๊ณ ๋งํ๋ ์ด์ ์ ์ค์ฒด
FastAPI ์์ฒด๋ "ํ๋ ์์ํฌ ์์ ํ๋ ์์ํฌ"๋ค. HTTP๋ Starlette๊ฐ, ๋ฐ์ดํฐ ๊ฒ์ฆ์ Pydantic์ด, ASGI ์๋ฒ๋ Uvicorn์ด ๋ด๋นํ๋ค. FastAPI๋ ์ด๊ฒ๋ค์ ํ์ ํํธ ๊ธฐ๋ฐ ์ธํฐํ์ด์ค๋ก ๋ฌถ์ ๊ฒ.
FastAPI Depends() โ ํจ์ ์๊ทธ๋์ฒ๋ก DIํ๋ ๋ฐฉ๋ฒ
DB ์ธ์ , ์ธ์ฆ, ํ์ด์ง๋ค์ด์ ์ ํจ์ ์ธ์๋ก ์ฃผ์ ํ๋ ํจํด
FastAPI์ Depends()๋ ํจ์๋ฅผ ์ธ์์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ฃ์ผ๋ฉด ์๋์ผ๋ก ํธ์ถ/์ฃผ์ ํด์ฃผ๋ DI ์์คํ ์ด๋ค. ์ค์ฒฉ ๊ฐ๋ฅํ๊ณ , generator๋ฅผ ์ฐ๋ฉด cleanup๋ ๋ณด์ฅ๋๋ค.
FastAPI์ async/await โ def์ async def์ ์ฐจ์ด
async def๋ฅผ ์ฐ๋ฉด ๋นจ๋ผ์ง๋? ๊ทธ๊ฑด ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๋ค๋ฅด๋ค
FastAPI์์ def๋ ์ค๋ ๋ํ์์, async def๋ ์ด๋ฒคํธ ๋ฃจํ์์ ์คํ๋๋ค. I/O ๋๊ธฐ๊ฐ ๋ง์ผ๋ฉด async๊ฐ ์ ๋ฆฌํ๊ณ , CPU ๋ฐ์ด๋๋ฉด def๊ฐ ๋ซ๋ค. ๋ ๋ค ์ง์ํ๋ ๊ฒ FastAPI์ ๊ฐ์ .
๐ธ Django
Django ORM ๋ด๋ถ โ QuerySet์ด lazyํ ์ด์
filter().exclude().order_by()๋ฅผ ์ฒด์ด๋ํด๋ SQL์ด ์ ๋๊ฐ๋ ์๋ฆฌ
Django์ QuerySet์ ํ๊ฐ(evaluate)๋๊ธฐ ์ ๊น์ง SQL์ ์คํํ์ง ์๋๋ค. filter/exclude/order_by๋ ๋ด๋ถ์ ์ผ๋ก SQL ์กฐ๊ฑด์ ์๊ธฐ๋ง ํ๊ณ , list()/for/[0] ๋ฑ์ผ๋ก ์ ๊ทผํ ๋ ๋น๋ก์ DB์ ์ฟผ๋ฆฌํ๋ค.
Django Middleware โ ์์ฒญ/์๋ต์ ๊ฐ์ธ๋ ์ํ ๊ตฌ์กฐ
MIDDLEWARE ์ค์ ์์๊ฐ ์ ์ค์ํ์ง, ๋ด๋ถ์์ ์ด๋ป๊ฒ ์ฒด์ด๋๋๋์ง
Django์ ๋ฏธ๋ค์จ์ด๋ ์ํ ๊ป์ง์ฒ๋ผ ๊ฒน๊ฒน์ด ๊ฐ์ธ๋ ๊ตฌ์กฐ๋ค. ์์ฒญ์ ๋ฐ๊นฅ์์ ์์ผ๋ก, ์๋ต์ ์์์ ๋ฐ์ผ๋ก ํต๊ณผํ๋ค. MIDDLEWARE ๋ฆฌ์คํธ์ ์์๊ฐ ์คํ ์์๋ฅผ ๊ฒฐ์ ํ๋ค.
Django Signals โ ์ด๋ฒคํธ ๊ธฐ๋ฐ ๋์จํ ๊ฒฐํฉ
post_save, pre_delete๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ด๋ป๊ฒ ๋์ํ๋๊ฐ
Django Signal์ Observer ํจํด์ ๊ตฌํ์ด๋ค. ๋ชจ๋ธ์ด ์ ์ฅ/์ญ์ ๋ ๋ ๋ฑ๋ก๋ receiver ํจ์๋ฅผ ์๋์ผ๋ก ํธ์ถํ๋ค. ํธ๋ฆฌํ์ง๋ง ๋จ์ฉํ๋ฉด ๋๋ฒ๊น ์ด ์ด๋ ค์์ง๋ค.
๐ฆ ์์ฃผ ์ฐ๋ ํจํค์ง
requests ๋ด๋ถ ๊ตฌ์กฐ โ requests.get()์ด ์ค์ ๋ก ํ๋ ์ผ
Session, PreparedRequest, HTTPAdapter, urllib3๊น์ง์ ํธ์ถ ์ฒด์ธ
requests.get(url)์ ๋ด๋ถ์ ์ผ๋ก Session ์์ฑ โ PreparedRequest ์กฐ๋ฆฝ โ HTTPAdapter ์ ํ โ urllib3.PoolManager๋ก ์ค์ TCP ์ฐ๊ฒฐ์ ๊ฑฐ์น๋ค. ์ด ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ์๋ฉด ์ปค๋ฅ์ ํ, ํ์์์, ์ฌ์๋๋ฅผ ์ ๋๋ก ์ค์ ํ ์ ์๋ค.
Pydantic ๋ด๋ถ โ ํ์ ํํธ๊ฐ ๋ฐํ์ ๊ฒ์ฆ์ด ๋๋ ๊ณผ์
__annotations__ โ Rust ์ฝ์ด(pydantic-core) โ ๊ฒ์ฆ ์คํ
Pydantic v2๋ ๋ชจ๋ธ ํด๋์ค๋ฅผ ์ ์ํ ๋ __annotations__๋ฅผ ์ฝ์ด์ Rust๋ก ์์ฑ๋ pydantic-core์ ๊ฒ์ฆ ์คํค๋ง๋ฅผ ์์ฑํ๋ค. __init__์์ ๊ฐ์ ๋ฃ์ ๋ ์ด ์คํค๋ง๋ก ๊ฒ์ฆ์ด ์คํ๋๋ค.
Click โ Python CLI ๋๊ตฌ๋ฅผ ๋ง๋๋ ๊ฐ์ฅ ๊น๋ํ ๋ฐฉ๋ฒ
decorator ๊ธฐ๋ฐ CLI ํ๋ ์์ํฌ์ ๋ด๋ถ ๋์
Click์ decorator๋ก CLI ์ธ์/์ต์ ์ ์ ์ํ๋ ํ๋ ์์ํฌ๋ค. argparse๋ณด๋ค ์ง๊ด์ ์ด๊ณ , Flask ๊ฐ๋ฐ์(Armin Ronacher)๊ฐ ๋ง๋ค์๋ค. @click.command + @click.option์ผ๋ก CLI๊ฐ ์์ฑ๋๋ค.