>  기사  >  백엔드 개발  >  완벽한 Python 프로젝트 구축

완벽한 Python 프로젝트 구축

coldplay.xixi
coldplay.xixi앞으로
2020-09-29 16:39:112624검색

python 동영상 튜토리얼 칼럼에서는 완벽한 Python 프로젝트를 빌드하는 방법을 소개합니다.

완벽한 Python 프로젝트 구축

새로운 Python 프로젝트를 시작할 때 바로 시작하여 코딩을 시작하는 것은 쉽습니다. 실제로, 약간의 시간을 들여 우수한 라이브러리를 선택하면 향후 개발에 많은 시간을 절약하고 더 행복한 코딩 경험을 가져올 수 있습니다.

이상적인 세상에서는 모든 개발자 간의 관계가 상호 의존적이고 관련되어 있습니다(협업 개발). 코드는 완벽하게 형식화되어야 하며 낮은 수준의 오류는 없어야 하며 테스트는 모든 코드를 포괄합니다. 게다가 모든 커밋에서 이 모든 것이 보장됩니다. (균일한 코드 스타일, 유형 감지, 높은 테스트 범위, 자동 감지)

이 글에서는 이러한 점을 달성할 수 있는 프로젝트를 빌드하는 방법을 소개하겠습니다. 단계를 따르거나 cookiecutter로 프로젝트 빌드 섹션(숙련된 사용자의 경우)으로 바로 이동할 수 있습니다. 먼저 새 프로젝트 디렉토리를 생성해 보겠습니다.

mkdir best_practices
cd best_practices复制代码

pipx Python 타사 라이브러리를 설치하는 명령줄 도구

Pipx는 Python 타사 라이브러리를 빠르게 설치하는 데 사용할 수 있는 명령줄 도구입니다. 이를 사용하여 Pipenv 및 Cookiecutter를 설치합니다. 다음 명령을 통해 pipx를 설치하십시오.

python3 -m pip install --user pipx
python3 -m pipx ensurepath复制代码

종속성 관리를 위해 Pipenv 사용

Pipenv는 프로젝트에 대한 virtualenv(가상 환경)를 자동으로 생성 및 관리하고 패키지를 설치/제거할 때 Pipfile에서 패키지를 추가/제거합니다. 또한 종속성의 신뢰성을 보장하기 위해 매우 중요한 Pipfile.lock을 생성합니다.

당신과 팀원이 동일한 라이브러리 버전을 사용하고 있다는 것을 알면 프로그래밍의 자신감과 재미가 크게 높아질 것입니다. Pipenv는 동일한 라이브러리를 다른 버전으로 사용하는 문제를 매우 잘 해결합니다. Pipenv는 지난 기간 동안 광범위한 관심과 인지도를 얻었으며 안심하고 사용할 수 있습니다. 설치 명령은 다음과 같습니다.

pipx install pipenv复制代码

black 및 isort를 사용한 코드 형식 지정

black은 코드 형식을 지정할 수 있습니다.

Black은 타협하지 않는 Python 코드 형식 지정 라이브러리입니다. 이를 사용하면 코드 형식을 수동으로 조정하는 세부 사항을 무시하게 됩니다. 그 대가로 Black은 속도와 확실성을 제공하고 Python 코딩 스타일을 조정하는 번거로움을 없애고 더 중요한 일에 집중할 수 있는 더 많은 에너지와 시간을 제공합니다.

어떤 종류의 프로젝트를 읽고 있더라도 검은색으로 포맷된 코드는 동일하게 보입니다. 잠시 후 형식 지정 문제가 줄어들고 콘텐츠에 더 집중할 수 있습니다.

black은 코드 차이를 줄여 코드 검사를 더 빠르게 만듭니다.

그리고 isort는 가져오기 부분을 정렬합니다.

isort는 가져오는 Python 패키지 부분(가져오기)을 정렬하므로 더 이상 가져오기 항목을 수동으로 정렬할 필요가 없습니다. 수입품을 알파벳순으로 정렬하고 자동으로 여러 부분으로 나눌 수 있습니다.

배포가 복잡해지지 않도록 Pipenv를 사용하여 설치합니다(개발 환경에서만 설치하도록 지정할 수 있음):

pipenv install black isort --dev复制代码

Black 및 isort는 기본 옵션과 호환되지 않으므로 isort가 다음 원칙을 따르도록 하겠습니다. 검은색. setup.cfg 파일을 생성하고 다음 구성을 추가합니다. setup.cfg 文件并添加以下配置:

[isort]
multi_line_output=3
include_trailing_comma=True
force_grid_wrap=0
use_parentheses=True
line_length=88复制代码

我们可以使用以下命令运行这些工具:

pipenv run black
pipenv run isort复制代码

使用 flake8 保证代码风格

Flake8 确保代码遵循 PEP8 中定义的标准 Python 代码规范。使用 pipenv 安装:

pipenv install flake8 --dev复制代码

就像 isort 一样,它需要一些配置才能很好地与 black 配合使用。将这些配置添加到 setup.cfg

[flake8]
ignore = E203, E266, E501, W503
max-line-length = 88
max-complexity = 18
select = B,C,E,F,W,T4复制代码

现在我们可以运行 flake8 了,命令:pipenv run flake8

使用 mypy 进行静态类型检查

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

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

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

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

[mypy]files=best_practices,testignore_missing_imports=true复制代码

다음 명령을 사용하여 이러한 도구를 실행할 수 있습니다.

pipenv run mypy复制代码

flake8을 사용하여 코드 스타일

Flake8은 코드가 PEP8에 정의된 표준 Python 코딩 규칙을 따르도록 보장합니다. Pipenv를 사용하여 설치:

pipenv install pytest pytest-cov --dev复制代码
🎜 isort와 마찬가지로 black과 잘 작동하려면 몇 가지 구성이 필요합니다. setup.cfg에 다음 구성을 추가하세요. 🎜
# content of test_sample.pydef inc(x):
    return x + 1def test_answer():
    assert inc(3) == 5复制代码
🎜이제 pipenv run flake8 명령을 사용하여 flake8을 실행할 수 있습니다. 🎜

mypy를 사용한 정적 유형 검사🎜🎜🎜Mypy는 동적(또는 "덕") 타이핑과 정적 타이핑의 장점을 결합하도록 설계된 Python용 비강제 정적 유형 검사기입니다. . Mypy는 Python의 강력한 표현력과 편리함을 강력한 유형 시스템의 컴파일 시간 유형 검사와 결합하여 본질적으로 런타임 오버헤드 없이 Python VM을 사용하여 실행합니다. 🎜🎜🎜Python에서 유형을 사용하는 데 익숙해지는 데 약간의 시간이 걸리지만 이점은 엄청납니다. 다음과 같습니다: 🎜
  • 정적 타이핑은 프로그램을 더 쉽게 이해하고 유지 관리할 수 있게 해줍니다.
  • 정적 타이핑은 오류를 조기에 발견하고 테스트 및 디버깅 시간을 줄이는 데 도움이 됩니다.
  • 정적 타이핑 코드가 프로덕션에 들어가기 전에 찾기 어려운 버그를 잡는 데 도움이 될 수 있습니다.
$ 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 =========================复制代码
🎜기본적으로 Mypy는 가져온 모든 패키지의 유형 주석을 재귀적으로 확인하고 라이브러리에 이러한 주석이 포함되어 있지 않은 경우 , 오류가 보고됩니다. 코드에서만 실행되고 유형 주석 없이 가져오기 오류를 무시하도록 mypy를 구성해야 합니다. 우리 코드가 아래 구성된 best_practices 패키지에 있다고 가정합니다. setup.cfg에 다음을 추가하세요. 🎜
[tool:pytest]
testpaths=test复制代码
🎜이제 mypy를 실행할 수 있습니다. 🎜
[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__.:复制代码
🎜여기에 유용한 치트 시트가 있습니다. 🎜

用 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视频教程

위 내용은 완벽한 Python 프로젝트 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제