728x90

https://outlore.dev/blog/python-dev-2024/

 

How I manage Python in 2024

No more frustration

outlore.dev

 

๋ณธ๊ธ€์€ outlore.dev์˜ ๊ธ€์„ OpenAI๋กœ ๋ฒˆ์—ญํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

 

๋” ์ด์ƒ ์ŠคํŠธ๋ ˆ์Šค ๋ฐ›์„ ํ•„์š” ์—†์Œ

 ์ง€๋‚œ 5๋…„๊ฐ„ Python ๊ฐœ๋ฐœ์€ ๋ˆˆ๋ถ€์‹œ๊ฒŒ ๋ฐœ์ „ํ•ด ์™”์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์ฃผ๋กœ JavaScript ๊ฐœ๋ฐœ์ž์ด์ง€๋งŒ, ๋ฒ„์ „ ๋ฐ ์˜์กด์„ฑ ๊ด€๋ฆฌ, ์ฝ”๋“œ ํฌ๋งทํŒ…, ๋ฆฐํŒ…, ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ์ œ๊ณตํ•˜๋Š” ๋„๊ตฌ๋“ค์ด ์„ฑ์žฅํ•˜๋Š” ๊ฒƒ์„ ๋ณด๋ฉฐ ๊ธฐ๋ปค์Šต๋‹ˆ๋‹ค.

 

์š”์•ฝ:

  • Python ๋ฒ„์ „ ๊ด€๋ฆฌ๋Š” mise
  • ๊ฐ€์ƒ ํ™˜๊ฒฝ ๊ด€๋ฆฌ๋Š” mise
  • ์˜์กด์„ฑ ๊ด€๋ฆฌ๋Š” poetry ๋˜๋Š” uv
  • ํฌ๋งทํŒ…๊ณผ ๋ฆฐํŒ…์€ ruff
  • ๋Ÿฐํƒ€์ž„ ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ๋Š” pydantic

Python ๋ฒ„์ „ ๊ด€๋ฆฌ

 ์ €๋Š” mise๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Mise๋Š” Python๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Go, Node.js, ๊ธฐํƒ€ ์–ธ์–ด ๋ฐ ๋Ÿฐํƒ€์ž„์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Mise๋Š” ํŒ€์˜ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์ด๋ฏธ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋Š” .python-version ๋ฐ .tool-versions ํŒŒ์ผ์„ ์ง€์›ํ•˜๋ฉฐ, .mise.toml ํŒŒ์ผ์„ ํ†ตํ•ด ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

.mise.toml ์˜ˆ์ œ:

[tools]
python = "3.11"

[env]
_.python.venv = { path = ".venv", create = true } # ๊ฐ€์ƒ ํ™˜๊ฒฝ์ด ์—†์œผ๋ฉด ์ƒ์„ฑ

Mise๊ฐ€ ๋Œ€์ฒดํ•˜๋Š” ๋„๊ตฌ:

  • pyenv
  • asdf (๊ฐ€์žฅ ์œ ์‚ฌํ•œ ๋„๊ตฌ)
  • brew Python ๋“ฑ

๊ฐ€์ƒ ํ™˜๊ฒฝ

 ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ ์‚ฌ์šฉํ•˜๋ฉด ์‹œ์Šคํ…œ Python์ด ์„ค์น˜๋œ ํŒจํ‚ค์ง€๋กœ ์˜ค์—ผ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (JavaScript ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ์ด๋ฅผ node_modules ๋””๋ ‰ํ† ๋ฆฌ์™€ ์œ ์‚ฌํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.) Mise๋Š” ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด ์ฃผ๋ฏ€๋กœ ํ”„๋กœ์ ํŠธ๋ณ„๋กœ ๋ณ„๋„์˜ ํ™˜๊ฒฝ์„ ์œ ์ง€ํ•˜๊ธฐ๊ฐ€ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

 

Mise๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ Python ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์ˆ˜๋™์œผ๋กœ ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

python -m venv .venv

 

Mise๊ฐ€ ๋Œ€์ฒดํ•˜๋Š” ๋„๊ตฌ:

  • virtualenvwrapper
  • pipenv ๋“ฑ

์˜์กด์„ฑ ๊ด€๋ฆฌ

์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋”ฐ๋ผ uv์™€ poetry ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  • uv:
    uv๋Š” pip์„ ๋Œ€์ฒดํ•˜๋Š” ๋น ๋ฅธ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ uv venv ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. uv๋Š” ํ–ฅํ›„ API ํ‘œ๋ฉด์ด ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋‹ˆ ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • poetry:
    ๊ตฌ์กฐํ™”๋œ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. JavaScript์˜ npm๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋ฉฐ, pyproject.toml ํŒŒ์ผ์ด package.json๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. poetry๋Š” ๊ฐ€์ƒ ํ™˜๊ฒฝ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์ด๋ฏธ ์ƒ์„ฑ๋œ ํ™˜๊ฒฝ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

pyproject.toml ์˜ˆ์ œ:

[tool.poetry]
name = "poetry-demo"
version = "0.1.0"
description = ""
authors = ["Sรฉbastien Eustace <sebastien@eustace.io>"]
readme = "README.md"
packages = [{include = "poetry_demo"}]

[tool.poetry.dependencies]
python = "^3.7"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Mise์™€ Poetry์˜ ์กฐํ•ฉ์€ ๋ฒ„์ „ ๊ด€๋ฆฌ์™€ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋Œ€์ฒด ๋„๊ตฌ:

  • pip
  • pip-tools ๋“ฑ

ํฌ๋งทํŒ…๊ณผ ๋ฆฐํŒ…

  • ruff:
    ์ฝ”๋“œ ํฌ๋งทํŒ…, ๋ฆฐํŒ…, import ์ •๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. VSCode ํ™•์žฅ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • Pylance:
    ํƒ€์ž… ๊ฒ€์‚ฌ ๋ฐ ๋ถ„์„์„ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. VSCode์—์„œ ํƒ€์ž… ์ฒดํฌ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด .vscode/settings.json์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”:
    {
    "python.analysis.typeCheckingMode": "basic"
    }

Ruff๊ฐ€ ๋Œ€์ฒดํ•˜๋Š” ๋„๊ตฌ:

  • black
  • pylint
  • isort
  • autopep8 ๋“ฑ
๋”๋ณด๊ธฐ

Tip. Visual Studio Code Formatter ๋‹จ์ถ•ํ‚ค Option + Shift + f


๋Ÿฐํƒ€์ž„ ์Šคํ‚ค๋งˆ

  • pydantic:
    ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๊ณ  ์ง๋ ฌํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. Python์—์„œ TypeScript์˜ zod์™€ ์œ ์‚ฌํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€์ฒด ๋„๊ตฌ:

  • dataclasses ๋“ฑ

 

 

 

 
๋ฐ˜์‘ํ˜•
๋‹คํ–ˆ๋‹ค