Heim > Artikel > Backend-Entwicklung > Erstellen Sie ein perfektes Python-Projekt
Die Kolumne
Python-Video-Tutorial stellt vor, wie man ein perfektes Python-Projekt erstellt.
Wenn Sie ein neues Python-Projekt starten, können Sie ganz einfach direkt loslegen und mit dem Codieren beginnen. Wenn Sie sich ein wenig Zeit nehmen, um hervorragende Bibliotheken auszuwählen, können Sie bei der zukünftigen Entwicklung viel Zeit sparen und ein angenehmeres Codierungserlebnis erzielen.
In einer idealen Welt ist die Beziehung zwischen allen Entwicklern voneinander abhängig und miteinander verbunden (kollaborative Entwicklung), der Code muss perfekt formatiert sein, es gibt keine Fehler auf niedriger Ebene und die Tests decken den gesamten Code ab. Darüber hinaus wird all dies bei jedem Commit garantiert. (Einheitlicher Codestil, Typerkennung, hohe Testabdeckung, automatische Erkennung)
In diesem Artikel werde ich vorstellen, wie man ein Projekt erstellt, das diese Punkte erreichen kann. Sie können den Schritten folgen oder direkt zum Abschnitt „Projekt mit Cookie-Cutter erstellen“ springen (für erfahrene Benutzer).
Erstellen wir zunächst ein neues Projektverzeichnis: mkdir best_practices
cd best_practices复制代码
pipx Ein Befehlszeilentool zum Installieren von Python-Bibliotheken von Drittanbietern.
python3 -m pip install --user pipx python3 -m pipx ensurepath复制代码
Verwenden Sie Pipenv für die Abhängigkeitsverwaltung
Pipenv erstellt und verwaltet automatisch Virtualenv (virtuelle Umgebung) für Ihr Projekt und fügt Pakete zu Pipfile hinzu bzw. entfernt sie, wenn Pakete installiert/deinstalliert werden. Außerdem wird das sehr wichtige Pipfile.lock generiert, um die Zuverlässigkeit der Abhängigkeiten sicherzustellen.Wenn Sie wissen, dass Sie und Ihre Teamkollegen dieselbe Bibliotheksversion verwenden, erhöht das das Selbstvertrauen und den Spaß am Programmieren erheblich. Pipenv löst das Problem der Verwendung derselben Bibliothek mit unterschiedlichen Versionen sehr gut. Pipenv hat in der vergangenen Zeit große Aufmerksamkeit und Anerkennung erlangt, und Sie können es bedenkenlos verwenden. Der Installationsbefehl lautet wie folgt:
pipx install pipenv复制代码
Codeformatierung mit Black und Isort
isort sortiert die Python-Paketteile (Importe), die Sie importieren, sodass Sie die Importe nicht mehr manuell sortieren müssen. Es kann Importe alphabetisch sortieren und automatisch in Teile aufteilen.Egal welche Art von Projekt Sie lesen, mit Schwarz formatierter Code sieht immer gleich aus. Nach einer Weile wird die Formatierung weniger problematisch und Sie können sich mehr auf den Inhalt konzentrieren.
black beschleunigt die Codeprüfung, indem es Codeunterschiede reduziert.
Und isort sortiert unseren Importteil:
Verwenden Sie Pipenv, um es zu installieren, damit die Bereitstellung nicht überladen wird (kann die Installation nur in der Entwicklungsumgebung festlegen):
pipenv install black isort --dev复制代码
Black und isort sind nicht mit den Standardoptionen kompatibel, daher lassen wir isort die Prinzipien von befolgen Schwarz. Erstellen Sie eine setup.cfg
-Datei und fügen Sie die folgende Konfiguration hinzu:
[isort] multi_line_output=3 include_trailing_comma=True force_grid_wrap=0 use_parentheses=True line_length=88复制代码
Wir können diese Tools mit dem folgenden Befehl ausführen: setup.cfg
文件并添加以下配置:
pipenv run black pipenv run isort复制代码
我们可以使用以下命令运行这些工具:
pipenv install flake8 --dev复制代码
Flake8 确保代码遵循 PEP8 中定义的标准 Python 代码规范。使用 pipenv 安装:
[flake8] ignore = E203, E266, E501, W503 max-line-length = 88 max-complexity = 18 select = B,C,E,F,W,T4复制代码
就像 isort 一样,它需要一些配置才能很好地与 black 配合使用。将这些配置添加到 setup.cfg
:
pipenv install mypy --dev复制代码
现在我们可以运行 flake8 了,命令:pipenv run flake8
。
Mypy 是 Python 的非强制的静态类型检查器,旨在结合动态(或 “鸭子”)类型和静态类型的优点。Mypy 将 Python 的表达能力和便利性与功能强大的类型系统的编译时类型检查结合在一起,使用任何 Python VM 运行它们,基本上没有运行时开销。
在 Python 中使用类型需要一点时间来适应,但是好处却是巨大的。如下:
[mypy]files=best_practices,testignore_missing_imports=true复制代码
默认情况下,Mypy 将递归检查所有导入包的类型注释,当库不包含这些注释时,就会报错。我们需要将 mypy 配置为仅在我们的代码上运行,并忽略没有类型注释的导入错误。我们假设我们的代码位于以下配置的 best_practices
包中。将此添加到 setup.cfg
pipenv run mypy复制代码
Flake8 stellt sicher, dass der Code den in PEP8 definierten Standard-Python-Codierungskonventionen folgt. Installation mit Pipenv:
pipenv install pytest pytest-cov --dev复制代码
Genau wie bei Isort ist eine gewisse Konfiguration erforderlich, um gut mit Schwarz zu funktionieren. Fügen Sie diese Konfigurationen zu setup.cfg
hinzu:
# content of test_sample.pydef inc(x): return x + 1def test_answer(): assert inc(3) == 5复制代码🎜Jetzt können wir flake8 mit dem Befehl ausführen:
pipenv run flake8
. 🎜$ pipenv run pytest=========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-5.x.y, py-1.x.y, pluggy-0.x.y cachedir: $PYTHON_PREFIX/.pytest_cache rootdir: $REGENDOC_TMPDIR collected 1 item test_sample.py F [100%] ================================= FAILURES ================================= _______________________________ test_answer ________________________________ def test_answer():> assert inc(3) == 5E assert 4 == 5 E + where 4 = inc(3) test_sample.py:6: AssertionError ========================= 1 failed in 0.12 seconds =========================复制代码🎜Standardmäßig überprüft Mypy rekursiv die Typanmerkungen aller importierten Pakete und wenn die Bibliothek diese Anmerkungen nicht enthält , es wird ein Fehler gemeldet. Wir müssen mypy so konfigurieren, dass es nur auf unserem Code ausgeführt wird und Importfehler ohne Typanmerkungen ignoriert. Wir gehen davon aus, dass sich unser Code im unten konfigurierten
best_practices
-Paket befindet. Fügen Sie dies zu setup.cfg
hinzu: 🎜[tool:pytest] testpaths=test复制代码🎜Jetzt können wir mypy ausführen: 🎜
[run] source = best_practices [report] exclude_lines = # Have to re-enable the standard pragma pragma: no cover # Don't complain about missing debug-only code: def __repr__ if self\.debug # Don't complain if tests don't hit defensive assertion code: raise AssertionError raise NotImplementedError # Don't complain if non-runnable code isn't run: if 0: if __name__ == .__main__.:复制代码🎜Hier ist ein hilfreicher Spickzettel. 🎜
使用 pytest 编写测试非常容易,消除编写测试的阻力意味着可以快速的编写更多的测试!
pipenv install pytest pytest-cov --dev复制代码
这是 pytest 网站上的一个简单示例:
# content of test_sample.pydef inc(x): return x + 1def test_answer(): assert inc(3) == 5复制代码
要执行它:
$ pipenv run pytest=========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-5.x.y, py-1.x.y, pluggy-0.x.y cachedir: $PYTHON_PREFIX/.pytest_cache rootdir: $REGENDOC_TMPDIR collected 1 item test_sample.py F [100%] ================================= FAILURES ================================= _______________________________ test_answer ________________________________ def test_answer():> assert inc(3) == 5E assert 4 == 5 E + where 4 = inc(3) test_sample.py:6: AssertionError ========================= 1 failed in 0.12 seconds =========================复制代码
我们所有的测试代码都放在 test
目录中,因此请将此目录添加到 setup.cfg
:
[tool:pytest] testpaths=test复制代码
如果还想查看测试覆盖率。创建一个新文件 .coveragerc
,指定只返回我们的项目代码的覆盖率统计信息。比如示例的 best_practices
项目,设置如下:
[run] source = best_practices [report] exclude_lines = # Have to re-enable the standard pragma pragma: no cover # Don't complain about missing debug-only code: def __repr__ if self\.debug # Don't complain if tests don't hit defensive assertion code: raise AssertionError raise NotImplementedError # Don't complain if non-runnable code isn't run: if 0: if __name__ == .__main__.:复制代码
现在,我们就可以运行测试并查看覆盖率了。
pipenv run pytest --cov --cov-fail-under=100复制代码
--cov-fail-under=100
是设定项目的测试覆盖率如果小于 100% 那将认定为失败。
Git hooks 可让您在想要提交或推送时随时运行脚本。这使我们能够在每次提交/推送时,自动运行所有检测和测试。pre-commit 可轻松配置这些 hooks。
Git hook 脚本对于在提交代码审查之前,识别简单问题很有用。我们在每次提交时都将运行 hooks,以自动指出代码中的问题,例如缺少分号、尾随空白和调试语句。通过在 code review 之前指出这些问题,代码审查者可以专注于变更的代码内容,而不会浪费时间处理这些琐碎的样式问题。
在这里,我们将上述所有工具配置为在提交 Python 代码改动时执行(git commit),然后仅在推送时运行 pytest coverage(因为测试要在最后一步)。创建一个新文件 .pre-commit-config.yaml
,配置如下:
repos: - repo: local hooks: - id: isort name: isort stages: [commit] language: system entry: pipenv run isort types: [python] - id: black name: black stages: [commit] language: system entry: pipenv run black types: [python] - id: flake8 name: flake8 stages: [commit] language: system entry: pipenv run flake8 types: [python] exclude: setup.py - id: mypy name: mypy stages: [commit] language: system entry: pipenv run mypy types: [python] pass_filenames: false - id: pytest name: pytest stages: [commit] language: system entry: pipenv run pytest types: [python] - id: pytest-cov name: pytest stages: [push] language: system entry: pipenv run pytest --cov --cov-fail-under=100 types: [python] pass_filenames: false复制代码
如果需要跳过这些 hooks,可以运行 git commit --no-verify
或 git push --no-verify
现在,我们已经知道了理想项目中包含了什么,我们可以将其转换为 模板 从而可以使用单个命令生成一个包含这些库和配置的新项目:
pipx run cookiecutter gh:sourcery-ai/python-best-practices-cookiecutter复制代码
填写项目名称和仓库名称,将为您生成新的项目。
要完成设置,请执行下列步骤:
# Enter project directorycd <repo_name># Initialise git repogit init# Install dependenciespipenv install --dev# Setup pre-commit and pre-push hookspipenv run pre-commit install -t pre-commit pipenv run pre-commit install -t pre-push复制代码
模板项目包含一个非常简单的 Python 文件和测试,可以试用上面这些工具。在编写完代码觉得没问题后,就可以执行第一次 git commit
,所有的 hooks 都将运行。
虽然在提交时知道项目的代码始终保持最高水准是件令人兴奋的事情。但如果在代码已全部修改完成之后(提交时),再发现有问题还是会让人很不爽。所以,实时暴露出问题要好得多。
在保存文件时,花一些时间确保代码编辑器运行这些命令。有及时的反馈,这意味着你可以在代码还有印象的时候能迅速解决引入的任何小问题。
我个人使用一些出色的 Vim 插件来完成此任务:
欢迎热爱技术和开源的小伙伴加入 HG 推出的译文亦舞系列的翻译中来,可以留言告诉我们。
更多相关免费学习推荐:python视频教程
Das obige ist der detaillierte Inhalt vonErstellen Sie ein perfektes Python-Projekt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!