Python å·¥å ·é¾è®¾ç½®æå | AIçæåç¿»è¯
é®é¢ï¼ è¿ä¸ª Python 项ç®å·¥å ·æ¨èææ¡£è§£éäºä»ä¹ï¼æ¶µçäºå·²è®¾ç½®çå·¥å ·ï¼ruff, pre-commitï¼åæ¨èæ·»å çå·¥å ·ï¼uv, pyright/mypy, pre-commit hooks, pytest, bump-my-versionï¼ï¼
çæ¡ï¼
è¿ä»½ææ¡£æ¯ä¸ä¸ª Python å¼åè å·¥å ·æåï¼å®æè¿°äºé¡¹ç®ä¸å·²é ç½®çå 容ï¼ä»¥ååºæ·»å çé¢å¤å·¥å ·ï¼ä»¥æå代ç è´¨éãå®å ¨æ§åå¼åè ä½éªã以䏿¯å¯¹æ¯ä¸ªé¨åçå ¨é¢åè§£ï¼
â 已设置
1. ruff â ä»£ç æ£æ¥ + æ ¼å¼å
Ruff æ¯ä¸ä¸ªæå¿«ç Python linter åä»£ç æ ¼å¼åå·¥å ·ï¼ç¨ Rust ç¼åã宿¯ç°æç linter å¦ Flake8 åæ ¼å¼åå·¥å ·å¦ Black å¿« 10â100 åï¼å¹¶æ¯æè¶ è¿ 800 æ¡å ç½®è§åã
- å®ä¸æ¬¡æ¿æ¢äºè®¸å¤å·¥å ·ï¼Flake8ãBlackãisortãpydocstyleãpyupgradeãautoflake â å ¨é½éæå¨ä¸æ¬¾å·¥å ·ä¸ã
- å®å¨
pyproject.tomlä¸é ç½®äº é对æ§ç忽ç¥è§åï¼æå³çé对æ¬é¡¹ç®ä¸éç¨çç¹å®è§å被æå¶ï¼åªæææä¹çè¦åæä¼åºç°ã
ç¤ºä¾ pyproject.toml é
ç½®ï¼
[tool.ruff.lint]
select = ["E", "F", "UP", "B", "I"]
ignore = ["E501"] # é对æ§ç忽ç¥
2. pre-commit â æ¯æ¬¡æäº¤åçèªå¨åæ£æ¥
pre-commit æ¯ä¸ä¸ªæ¡æ¶ï¼å®å®è£
Git hooksï¼è¿æ ·æ¯æ¬¡è¿è¡ git commit æ¶ï¼é½ä¼èªå¨è¿è¡ ruffï¼ä»£ç æ£æ¥ï¼å ruff-formatï¼æ ¼å¼åï¼ãè¿å¯ä»¥é²æ¢æ ¼å¼ä¸è¯ææ£æ¥å¤±è´¥ç代ç è¿å
¥ä»åºã
ð§ æ¨èæ·»å
1. uv â ä¾èµç®¡çï¼é«ä¼å
级ï¼
uv æ¯æ¥èª Astral çå
åèæç¯å¢ç®¡çå¨ â å°±æ¯æå»º ruff çåä¸ä¸ªå¢éã宿¯ pip å venv çæ¿ä»£åã
- æ¿æ¢
pip install -e .为uv sync - å®çæ
uv.lockéæä»¶ï¼ç¡®ä¿è·¨æºå¨çå¯éç°å®è£ - 宿¯ pip å¿«å¾å¤
# è䏿¯ï¼
pip install -e .
# 使ç¨ï¼
uv sync
宿¹è¿æä¾äº astral-sh/uv-pre-commit ç pre-commit hookï¼å³ä½¿ pyproject.toml åçååï¼ä¹è½ä¿æ uv.lock æä»¶ææ°ã
2. pyright æ mypy â éæç±»åæ£æ¥ï¼ä¸ä¼å
级ï¼
è¿äºå·¥å
· ä¸è¿è¡ä»£ç å³å¯åææ¨ç代ç ï¼æè·ç±»åç¸å
³ç bugï¼ä¾å¦ï¼å¨ææ int çå°æ¹ä¼ å
¥ strï¼ã
æ·»å å° .pre-commit-config.yamlï¼
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.x.x
hooks:
- id: mypy
ææ¡£ç¹å«å¼ºè° æ¬é¡¹ç®æå¤§çå·®è·æ¯æ²¡æç±»åæ£æ¥ â å ä¸ºé¡¹ç®æ¶å LLM/å¤é¨ API è°ç¨ï¼å¹¶å¨ main.py ä¸ä½¿ç¨å¤æ¨¡åååï¼è¿æ£æ¯ç±»å bug æå±é©ä¸æé¾å¨è¿è¡æ¶è°è¯çå°æ¹ã
3. pre-commit-hooks â é¢å¤å®å
¨é©åï¼é«ä¼å
级ï¼
è¿äºæ¯æ¥èªå®æ¹ pre-commit-hooks ä»åºçè½»é级ãå¿«éæ£æ¥ãå°å®ä»¬æ·»å å° .pre-commit-config.yamlï¼
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace # ç§»é¤å°¾éç©ºæ ¼
- id: end-of-file-fixer # ç¡®ä¿æä»¶ä»¥æ¢è¡ç¬¦ç»æ
- id: check-yaml # éªè¯ YAML è¯æ³
- id: check-toml # éªè¯ TOML è¯æ³
- id: check-merge-conflict # æ£æµæªè§£å³çåå¹¶å²çªæ è®°
- id: debug-statements # æè·éçç print() æ breakpoint() è°ç¨
è¿äºé©åæè·å¸¸è§é®é¢ï¼å°¾éç©ºæ ¼ãæä»¶æ«å°¾ç¼ºå°æ¢è¡ç¬¦ãæ æ YAML è¯æ³ï¼ä»¥åæå¤æäº¤ç大æä»¶ã
4. pytest + pytest-cov â æµè¯ï¼ä½ä¼å
级ï¼
pytestï¼CLI å·¥å ·çæ å Python æµè¯è¿è¡å¨pytest-covï¼æ·»å è¦ççæ¥åï¼æµè¯è¦çäºå¤å°ä»£ç ï¼
ææ¡£æåºè¿æ¯ ä½ä¼å
级ï¼å 为 CLAUDE.md å£°ææ²¡ææµè¯å¥ä»¶ â ä½åå¨ tests/ ç®å½ï¼è¡¨ææµè¯å¯è½å¾å¿«æ·»å ã
uv run pytest --cov=src tests/
5. bump-my-version â åå¸ä¸çæ¬ç®¡çï¼ä½ä¼å
级ï¼
æ¤å·¥å
·ä¸ pyproject.toml éæï¼éè¿ CLI å½ä»¤ç®¡ççæ¬å级ãä¾å¦ï¼å®å¯ä»¥èªå¨å° version = "0.1.0" æ´æ°ä¸º version = "0.2.0"ï¼
bump-my-version bump minor
å®å¤çè·¨æä»¶çç»ä¸çæ¬ç®¡çï¼å¹¶å¯ä»¥èªå¨è§¦å Git æ ç¾åæäº¤ã
ð ä¼å 级æ»ç»è¡¨æ ¼
ð å ³é®è¦ç¹
ææ¡£æè¿°äºä¸ä¸ª åå±ä»£ç è´¨éçç¥ï¼
- æ ¼å¼å䏿£æ¥ï¼å·²å®æï¼â
ruff+pre-commit - ä¾èµå«ç â
uvï¼éæä»¶ãå¿«éå®è£ ï¼ - ç±»åå®å
¨ â
mypy/pyrightï¼æå ³é®çå·®è·ï¼ - æäº¤å«ç â
pre-commit-hooksï¼ææ·»å ãé«ä»·å¼ï¼ - æµè¯ â
pytest+ è¦çç - åå¸ç®¡ç â
bump-my-version
ä½è æåº éæç±»åæ£æ¥æ¯ #1 缺失é¨åï¼é´äºä»£ç åºçæ§è´¨ï¼LLM API è°ç¨ãå¤é¨æå¡ã夿¨¡åæ¶æï¼ã
åèèµæï¼
- Ruff Official Docs
- Ruff GitHub
- uv pre-commit integration
- How to set up pre-commit hooks for Python
- Ruff Tutorial â Real Python
