Heim  >  Artikel  >  Backend-Entwicklung  >  Erstellen Sie ein perfektes Python-Projekt

Erstellen Sie ein perfektes Python-Projekt

coldplay.xixi
coldplay.xixinach vorne
2020-09-29 16:39:112556Durchsuche

Die Kolumne

Python-Video-Tutorial stellt vor, wie man ein perfektes Python-Projekt erstellt.

Erstellen Sie ein perfektes Python-Projekt

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.

Pipx ist ein Befehlszeilentool, mit dem sich Python-Bibliotheken von Drittanbietern schnell installieren lassen. Wir werden dies verwenden, um Pipenv und Cookiecutter zu installieren. Installieren Sie pipx über den folgenden Befehl:

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

Black kann unseren Code formatieren:

Black ist eine kompromisslose Python-Codeformatierungsbibliothek. Durch die Verwendung entfallen die Details der manuellen Anpassung der Codeformatierung. Im Gegenzug bringt Black Geschwindigkeit, Sicherheit und die Vermeidung des Aufwands, den Python-Codierungsstil anzupassen, sodass mehr Energie und Zeit übrig bleibt, um sich auf wichtigere Dinge zu konzentrieren.

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:

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.

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 保证代码风格

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 进行静态类型检查

Mypy 是 Python 的非强制的静态类型检查器,旨在结合动态(或 “鸭子”)类型和静态类型的优点。Mypy 将 Python 的表达能力和便利性与功能强大的类型系统的编译时类型检查结合在一起,使用任何 Python VM 运行它们,基本上没有运行时开销。

在 Python 中使用类型需要一点时间来适应,但是好处却是巨大的。如下:

  • 静态类型可以使程序更易于理解和维护
  • 静态类型可以帮助您更早地发现错误,并减少测试和调试的时间
  • 静态类型可以帮助您在代码投入生产之前发现难以发现的错误
[mypy]files=best_practices,testignore_missing_imports=true复制代码

默认情况下,Mypy 将递归检查所有导入包的类型注释,当库不包含这些注释时,就会报错。我们需要将 mypy 配置为仅在我们的代码上运行,并忽略没有类型注释的导入错误。我们假设我们的代码位于以下配置的 best_practices 包中。将此添加到 setup.cfg

pipenv run mypy复制代码

Verwenden Sie flake8, um sicherzustellen Codestil

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 . 🎜

Statische Typprüfung mit mypy🎜🎜🎜Mypy ist eine nicht erzwungene statische Typprüfung für Python, die die Vorteile der dynamischen (oder „Duck“)-Typisierung und der statischen Typisierung kombiniert . Mypy kombiniert die Ausdruckskraft und den Komfort von Python mit der Typprüfung eines leistungsstarken Typsystems zur Kompilierungszeit und führt sie mit jeder Python-VM praktisch ohne Laufzeitaufwand aus. 🎜🎜🎜Die Verwendung von Typen in Python ist etwas gewöhnungsbedürftig, aber die Vorteile sind enorm. Wie folgt: 🎜
  • Statische Typisierung kann das Verständnis und die Wartung von Programmen erleichtern
  • Statische Typisierung kann Ihnen helfen, Fehler früher zu finden und die Test- und Debugging-Zeit zu verkürzen
  • Statische Typisierung kann Ihnen helfen, schwer zu findende Fehler zu erkennen, bevor Ihr Code in die Produktion geht
$ 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 和 pytest-cov 进行测试

使用 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% 那将认定为失败。

pre-commit 的 Git hooks

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-verifygit push --no-verify

使用 cookiecutter 生成项目

现在,我们已经知道了理想项目中包含了什么,我们可以将其转换为 模板 从而可以使用单个命令生成一个包含这些库和配置的新项目:

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 插件来完成此任务:

  • ale 实时运行 flake8 并在保存文件时运行 black、isort 和 mypy
  • 与 projectionist 集成的 vim-test 在文件保存上运行 pytest

欢迎热爱技术和开源的小伙伴加入 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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen