2021年新项目的Python最佳实践
介绍
本教程的目标是描述Python开发生态系统。对于从另一种编程语言来使用Python的人来说,这是很有帮助的。
他们说你应该坚持算法和数据结构,你可以在几周内学习一门新的语言,这只是一种新的语法。我完全同意算法和数据结构是非常重要的,但是对于语言来说,它不仅仅是语法。它周围有一整套工具和最佳实践的基础设施。对于来自不同背景的人来说,跟上所有这些东西可能是势不可挡的,特别是考虑到有时信息应该在不同的地方找到。
这是我非常固执己见的尝试,试图编译一些关于为本地开发建立一个新的Python环境的最佳实践。还有一些关于将这些工具与VisualStudio代码集成的建议,但是,没有必要使用这个特定的编辑器。我将更新此页面,因为底层工具有一些更改。我还计划自己使用它作为启动新Python项目的样板。本教程很长,因为我详细解释了这些工具的用途和用法,但是,最终的结果是快速设置新的项目环境,只需几分钟就可以实现。西西。
如何使用pyenv管理Python版本?
为什么要用pyenv?
许多教程的开头都是一样的:Python.org并为您下载最新版本的语言平台。别听他们的。还有更好的办法。这就是为什么。
Python有不同的版本,在处理不同的项目时,需要在这些版本之间切换。
您的操作系统可能已经有了一些Python版本。对于Mac,它是2.7,一些Linux发行版已经切换到版本3。更多的是,还有另一个Python作为Anaconda包的一部分安装。底线是:在键入python
在命令行。
在某种程度上,您的机器上会出现一堆不同的Python可执行文件,您需要某种方法来管理它。要是有这样的工具就好了。
而且确实有。它叫pyenv
- Https://github.com/pyenv/pyenv
如何安装pyenv?
安装Mac:
brew update brew install pyenv
对于Linux,您最好使用pyenv installer
- Https://github.com/pyenv/pyenv-installer :
curl https://pyenv.run | bash
对于Windows,有pyenv for Windows
- Https://github.com/pyenv-win/pyenv-win .
但是您最好还是使用WindowsSubSystemforLinux(WSL),然后以Linux的方式安装它。
如何使用pyenv?
首先,我们可以看到安装在计算机上的所有Python可执行文件(至少是那些)的列表。pyenv
能够找到):
pyenv versions
* system (set by /Users/alex/.python-version)
上面显示了我的机器的输出。这里的星号表示Python的当前活动版本。所以如果我跑
python -V
Python 2.7.16
我们可以看到MacOS仍然作为系统可执行文件随Python2.7一起提供。
现在让我们看看所有可用的Python版本:
pyenv install --list
这将输出一个不同Python版本的长列表。你会惊讶于那里有多少毕顿人。CPython实现默认为以下版本3.8.5
,其他的则有前缀,如pypy3.6-7.3.1
.
如果只想看到CPython版本,可以运行如下内容:
pyenv install --list | grep " 3\."
如果你用pyenv
有相当一段时间了,并且列表中没有新版本,您应该更新pyenv
本身:
brew upgrade pyenv
或
pyenv update
带有后缀的版本-dev
目前正在积极发展。
让我们在撰写本文时安装最新的、最稳定的Python版本
pyenv install 3.8.5
这将下载源代码并在计算机上编译它:
python-build: use <a href="/cdn-cgi/l/email-protection" data-cfemail="dfb0afbab1acacb39feef1ee">[email protected]</a> from homebrew python-build: use readline from homebrew Downloading Python-3.8.5.tar.xz... -> https://www.python.org/ftp/python/3.8.5/Python-3.8.5.tar.xz Installing Python-3.8.5... python-build: use readline from homebrew python-build: use zlib from xcode sdk Installed Python-3.8.5 to /Users/alex/.pyenv/versions/3.8.5
如果我们跑pyenv versions
同样,我们在列表中看到了我们的新版本,但它仍然不活跃
* system (set by /Users/alex/.python-version)3.8.5
我们可以用python -V
。仍然
Python 2.7.16
pyenv
允许我们将Python的任何版本设置为全局Python解释器,但我们不会这样做。可以有一些脚本或其他程序依赖于默认的解释器,所以我们不想搞砸这件事。相反,我们将设置每个项目的Python。让我们在下一节中创建一个项目。
替代工具:asdf
: Https://asdf-vm.com/
Python与诗歌的依赖管理
为什么要用诗歌?
默认情况下,Python包是与pip install
。实际上,没有人这样使用它。它将所有的依赖项安装到Python解释器的一个版本中,这会扰乱依赖关系。
安装每个项目的依赖关系是一个很好的实践。因此,每个项目只包含它所需的依赖项,仅此而已。这也防止了不同项目所需的不同包的版本之间的冲突。
为了解决这一问题,提出了虚拟环境的概念。因此,每个项目都有自己的虚拟环境,具有固定的Python版本和特定于该项目的固定依赖关系。
虚拟环境是从venv
, virtualenv
, virtualenvwrapper
到pipenv
,和poetry
. pipenv
很受欢迎,很长一段时间以来都是个不错的选择。关于pipenv
这篇博客文章对此做了大量报道:皮潘夫:承诺很多,却很少。克里斯·沃里克。最大的担忧之一是延迟发布--自2018年以来没有新版本发布。虽然,2020年中期pipenv
随着几个新的更新,许多开发人员已经下定决心了。诗歌获得了一些吸引力,此外,它还声称更好在以下情况下解析依赖项pipenv
失败了。此外,诗歌可以帮助开源项目,因为它有助于发布包。
诗歌官方网站:Https://python-poetry.org/
如何安装诗歌?
所以,让我们开始吧。建议在系统级别上安装诗歌。
对于MacOS、Linux和WSL:
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
如果在Windows中使用Powershell,则在官方网站但我个人建议只使用WSL。
若要为当前shell会话应用更改,请运行
source $HOME/.poetry/env
您可以将其添加到自动运行的shell脚本中,如.bashrc
或.zshrc
如果Poetry
不会出现在新的shell会话中:
export PATH="$HOME/.poetry/bin:$PATH"
还可以为shell启用选项卡完成。描述了这一过程。这里 .
如何用诗歌创造新项目?
诗歌为您创建一个文件夹结构,因此请确保将当前目录更改为新项目的父目录,然后运行:
poetry new my-project
哪里my-project
是项目的名称。将项目名称改为。
现在,让我们看看Poetry
为我们创建:
cd my-project; ls
如何设置每个项目的Python版本?
我们还在使用旧的Python2.7,记得吗?对于我们的新项目,我们希望使用Python的现代版本,所以我们回到pyenv
工具。由于我们仍然在项目目录中,请在本地为该目录设置Python版本:
pyenv local 3.8.5
如果我们跑pyenv versions
现在,我们可以看到3.8.5被标记为星号,因此它对这个目录是活动的。请注意,在此目录之外,Python版本与以前相同。
system * 3.8.5 (set by /Users/alex/iCloud/dev/projects/my-project/.python-version)
我们可以再查一遍python -V
.
Python 3.8.5
现在,我们让“诗歌”摘取当前的Python版本:
poetry env use python
Creating virtualenv my-project-PSaGJAu6-py3.8 in /Users/alex/Library/Caches/pypoetry/virtualenvs Using virtualenv: /Users/alex/Library/Caches/pypoetry/virtualenvs/my-project-PSaGJAu6-py3.8
作为设置Python版本的最后一步,让我们更新pyproject.toml
. [tool.poetry.dependencies]
应该反映支持的Python版本为3.8或更高版本:
[tool.poetry] name = "my-project" version = "0.1.0" description = "" authors = ["Alex"][tool.poetry.dependencies] python = "^3.8"[tool.poetry.dev-dependencies] pytest = "^5.2"[build-system] requires = ["poetry-core>=1.0.0a5"] build-backend = "poetry.core.masonry.api"
如何使用诗歌?
在下一步中,您可能希望安装您的第一个依赖项:某个库或框架,您计划在这些库或框架的基础上构建项目。例如:
poetry add aiohttp
哪里aiohttp
是我们安装的框架。
如果您想要为本地开发安装它的依赖项,那么只需运行
poetry install
若要将所有依赖项切换到最新版本,请执行以下操作:
poetry update
如何使用诗歌与VS代码?
VS代码不会自动检测诗歌。好消息是,有一个简单的方法可以让VS代码检测到诗歌创造的虚拟环境。
首先,我们必须激活虚拟环境:
poetry shell
Spawning shell within /Users/alex/Library/Caches/pypoetry/virtualenvs/my-project-PSaGJAu6-py3.8 ➜ my-project . /Users/alex/Library/Caches/pypoetry/virtualenvs/my-project-PSaGJAu6-py3.8/bin/activate (my-project-PSaGJAu6-py3.8) ➜ my-project
现在,当我们在上述虚拟环境中时,我们可以从它调用VS代码:
code .
安装皮兰斯-VS代码的Python语言服务器。
当您打开任何Python文件时,VS代码立即要求我们选择Python解释器
所以让我们照他们的要求去做吧。因为我们在虚拟环境中调用VS代码,所以正确的解释器将显示为选项,我们可以选择它。
注意,3.8.5有两个选项,我们应该选择一个位于虚拟环境下的选项(参见文件路径,它应该包含virtualenv
).
一般来说,您可以喜欢这个Gizub问题,以便在VS代码中添加对诗歌的支持:Https://github.com/microsoft/vscode-python/issues/8372跟踪进展。布雷特·坎农说,VS代码团队正在重新工作环境发现代码,因此最终诗歌将完全得到VS代码的支持。
如何提升诗歌?
简单运行poetry self update
会撞上最新版本的诗歌。
如果你遇到错误
ImportError: No module named cleo
你需要重新安装诗歌,首先删除它:
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py > get-poetry.py python get-poetry.py --uninstall python get-poetry.py rm get-poetry.py
如何用诗歌和pyenv升级Python版本?
时间已经过去,新的Python版本也发布了。有新的特性和错误修复,所以我们希望在我们的项目中加入Python版本。这是一个非常简单的任务pyenv
还有诗歌。
首先,我们下载、编译和设置新的Python解释器。请确保不是在虚拟环境中运行此命令,而是从项目根文件夹运行此命令。在我的例子中,我将升级到CPython 3.9.2,这在编写本文时是可用的,但它可以是任何其他版本的CPython解释器。
pyenv install 3.9.2 pyenv local 3.9.2 pyenv versions
my-project pyenv versionssystem3.8.5 * 3.9.2 (set by /Users/alex/iCloud/dev/projects/my-project/.python-version)
接下来,我们让诗歌在虚拟环境中使用这个解释器。
poetry env use python
Creating virtualenv my-project-PSaGJAu6-py3.9 in /Users/alex.mitelman/Library/Caches/pypoetry/virtualenvs Using virtualenv: /Users/alex/Library/Caches/pypoetry/virtualenvs/my-project-PSaGJAu6-py3.9
请注意,项目哈希与以前相同,但Python版本现在为3.9。
由于我们有一个新的虚拟环境,我们必须重新安装它的所有依赖项:
poetry install
在下一步中,我们只需激活虚拟环境,并再次检查是否找到了正确的Python版本。我们还从虚拟环境中开始VS代码,因此它能够发现新的环境(确保在此之前关闭VS代码)。
poetry shell python -V code .
最后,在左下角单击Python并从列表中选择更新版本。确保您选择了虚拟环境版本。
The above images show version 3.9.0 that was used for the previous version of the article
别忘了更新[tool.poetry.dependencies]
分节pyproject.toml
文件以反映Python版本的支持。
VS代码将提示您选择Linter、代码格式化程序等。请暂时忽略这些提示。我们稍后将在本教程中设置它们。
备选方案:venv
-内置Python
如何用pytest测试?
为什么要使用吡替啶?
测试很重要,所以我们在创建项目后做的第一件事就是处理测试。
pytest
是一个广受欢迎的框架,被广泛采用。事实上,它非常受欢迎,它作为诗歌的默认测试框架。所以如果我们打开[tool.poetry.dev-dependencies]
分节pyproject.toml
我们可以看到pytest
已经被列为开发依赖项。
不仅如此,诗歌还为我们创建了测试文件夹结构。
cd tests; ls
__init__.py __pycache__ test_my_project.py
如何使用pytest与VS代码?
作为一个有意过于简化的示例,让我们创建和测试两个数字相乘的函数。根据TDD,我们首先创建测试。
让我们打开test_my_project.py
并添加函数的导入和非常简单的测试:
from my_project.math import multiply_two_numbersdef test_multiply_two_numbers():result = multiply_two_numbers(2, 3)assert result == 6
与其从终端运行我们的测试,不如利用代码编辑器。⇧⌘P-开始键入“Python:FindTest”并从下拉列表中选择它。(这里还有用于MacOS的keybord快捷方式)
测试框架选择出现在右下角。单击按钮:
并选择pytest
在下拉列表中:
作为最后一步,它要求您提供包含所有测试的目录:
VS代码发现了我们的测试,所以现在它添加了一些花哨的按钮来运行或调试特定的测试。
当我们使用VS代码运行测试时,它明显地将它们标记为红色,因为我们还没有实现该函数。
所以让我们创造math.py
文件在my_project
目录,然后实现我们的简单函数:
def multiply_two_numbers(a, b):return a * b
当我们再次运行测试时,它们现在被标记为绿色。
或者,您可以从命令行运行测试。
poetry run pytest
或者从激活的虚拟环境中
pytest
备选方案:unittest
-默认Python发行版包括在内。缺点:非Pythonic CamelCase API,语法稍难。
如何使用pytest-cov测量测试覆盖率?
哪里有检测,哪里就有报道。我们可以安装pytest-cov
插件pytest
要度量测试覆盖率:
poetry add --dev pytest-cov
现在,使用附加参数运行测试将生成覆盖报告:
pytest --cov=my_project tests/
================================================= test session starts ============= platform darwin -- Python 3.9.2, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 rootdir: /Users/alex/iCloud/dev/projects/my-project plugins: cov-2.10.1 collected 2 items tests/test_my_project.py .. [100%]----------- coverage: platform darwin, python 3.9.2 ----------- Name Stmts Miss Cover -------------------------------------------- my_project/__init__.py 1 0 100% my_project/math.py 4 0 100% -------------------------------------------- TOTAL 5 0 100%================================================== 2 passed in 0.08s ===============
这也会产生.coverage
在我们的版本控制中我们不想要的文件,所以我们不要忘记添加它.gitignore
:
echo '.coverage' > .gitignore
如何在提交前提交更改之前运行检查?
使用Git
我们还没有谈到版本控制,我们应该。显然,我们在2021年使用Git。安装或更新到最新版本。对于MacOS:
brew install git
如果还没有项目的存储库,我们应该创建它。GitHub创建新的存储库main
现在是默认分支,所以让我们也这样创建它:
git init -b main
首先,我们应该.gitignore
文件,因此我们不会将一些临时或二进制文件提交给回购。我们可以从这里手工复制粘贴Https://github.com/github/gitignore/blob/master/Python.gitignore或者简单地运行以下命令,该命令将创建.gitignore
并下载以上链接的内容到它中。您必须位于项目根目录中。
curl -s https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore >> .gitignore
您可以将VS代码设置文件夹排除在版本控制之外。此外,如果有人使用该代码编辑器,我们也可以排除PyCharm设置。
echo '.vscode/\n.idea/' >> .gitignore
同道
现在,让我们将到目前为止的所有内容添加到版本控制中:
git add .
为什么在提交之前运行检查?
如您所见(并将在本教程中进一步查看),该项目的样板很大。在将代码提交到远程回购之前,很容易错过一些东西或忘记应用一些检查。因此,代码不会通过CI自动化,您的同事或维护人员可能会要求您在代码评审期间对代码进行一些更改。所有这一切都是因为文件末尾缺少换行符这样的小挑剔。有换行符POSIX标准。即使你很清楚这一点,你也很容易忘记或错过这一点。所有这些都只是浪费时间,如果在提交代码之前有一些自动化,这是很容易避免的。而且确实有。
请欢迎 pre-commit
。它是对每个git提交运行自动检查的工具。它很容易使用,而且不需要根访问。顺便说一下,pre-commit
是用Python编写的,但可以用于各种编程语言的项目。
如何安装和使用预提交?
pre-commit
可以在系统级别上安装,但出于我们开始使用的原因,我们不想这样做。pyenv
-我们将使用不同的Python版本,我们的依赖关系应该是有序的。这就是为什么我们要安装pre-commit
作为发展依赖:
poetry add pre-commit --dev
接下来,我们将把所有的指针和其他东西放到预提交的钩子中。目前,我们将创建一个简单的配置,用于像我们作为示例讨论的文件换行符末尾这样的小东西。
有一个命令pre-commit
为我们创建一个示例文件。从我们的项目根执行:
pre-commit sample-config > .pre-commit-config.yaml
它创建一个配置文件,其内容如下:
# See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooksrev: v2.4.0hooks:- id: trailing-whitespace- id: end-of-file-fixer- id: check-yaml- id: check-added-large-files
我们可以看到pre-commit
已经为我们创造了一些方便的钩子。让我们看看它是如何工作的。若要手动运行检查,请执行以下操作:
pre-commit run --all-files
跑后pre-commit
,它已经发现,即使是由VS代码创建的文件在末尾不包含换行符!
Trim Trailing Whitespace.................................................Passed Fix End of Files.........................................................Failed - hook id: end-of-file-fixer - exit code: 1 - files were modified by this hookFixing my_project/math.py Fixing .vscode/settings.json Fixing tests/test_my_project.pyCheck Yaml...............................................................Passed Check for added large files..............................................Passed
pre-commit
实际上,我们已经修正了这个问题,所以如果我们再次运行相同的命令,那么所有的检查都会通过OK。
Trim Trailing Whitespace.................................................Passed Fix End of Files.........................................................Passed Check Yaml...............................................................Passed Check for added large files..............................................Passed
最重要的部分是让Git知道这些钩子,并在每次提交之前运行它们。
pre-commit install
pre-commit installed at .git/hooks/pre-commit
现在,我们可以提交更改:
git commit -m 'Initial commit'
Trim Trailing Whitespace.................................................Passed Fix End of Files.........................................................Passed Check Yaml...............................................................Passed Check for added large files..............................................Passed [master (root-commit) 7dc335f] Initial commit11 files changed, 559 insertions(+)create mode 100644 .gitignorecreate mode 100644 .pre-commit-config.yamlcreate mode 100644 .python-versioncreate mode 100644 .vscode/settings.jsoncreate mode 100644 README.rstcreate mode 100644 my_project/__init__.pycreate mode 100644 my_project/math.pycreate mode 100644 poetry.lockcreate mode 100644 pyproject.tomlcreate mode 100644 tests/__init__.pycreate mode 100644 tests/test_my_project.py
正如我们所看到的,钩子是在提交之前运行的。照计划做。
最后一件事,我们可以问pre-commit
要使配置更新到最新版本的工具,请执行以下操作:
pre-commit autoupdate
它立即为我更新钩子:
Updating https://github.com/pre-commit/pre-commit-hooks ... updating v2.4.0 -> v3.2.0.
用Flake8连接器进行代码分析
为什么在Python项目中使用Linter?
莱特斯站在与错误和错误的战斗的第一线。他们甚至在你运行密码之前就给你发了信号。显然,IDE支持指针,所以您甚至不必手动运行。在Linter的帮助下,IDE可以在您实际编写代码的时候正确地标记错误的代码。
在Python世界中,有很多指针,但是有两个主要的指针弗拉克8和皮林特 .
皮林特是一个非常严格和挑剔的林特。Google在内部将其用于Python项目,根据它们的指导方针。因为它是自然的,你可能会花费大量的时间去战斗或配置它。顺便说一句,这也许还不错。然而,这种严格性的结果可能是一种更安全的代码--更长的开发时间。
大多数流行的开源项目都使用Flake8。但是在我们开始之前,Python世界中还有另一个英雄我们应该谈谈。
Python样式指南-PEP 8
Python风格指南,更著名的是它的Python增强建议编号-PEP 8。每个Python开发人员都应该熟悉PEP 8,连同Python的禅宗(第20页)。
在阅读了PEP 8之后,您可能想知道是否有一种自动检查和执行这些指南的方法?Flake8正是这样做的,而且更多。它可以在开箱即用的情况下工作,并且可以进行配置,以防您想要更改某些特定设置。
虽然它没有皮林特那么严格,但它在第一道防线上还是做得很好。
这就是我建议坚持使用Flake8的原因。您仍然可以使用Pylint作为第二个Linter,但是Flake8是最起码的。
如何安装Flake 8?
VS代码将提示您为项目选择Linter。您也可以按⇧⌘P,开始键入“Linter”并选择“Python:selectLinter”。
然后选择“flake8”
VS代码应该获取您的虚拟环境,并将Flake8作为开发依赖项进行安装。
如果没有发生这种情况,或者您想从命令行安装它,下面是一种方法:
poetry add flake8 --dev
如何使用Flake 8?
回到我们在上一节中编写的代码的一小部分。VS代码标记为红色,一些Linter发现有问题的代码。通过设置指向该部分的指针,我们可以看到错误消息、错误号(我们可以在互联网上搜索)和标记错误的链接。
我们还可以手动运行Flake 8以查看相同的结果:
flake8 .
./tests/test_my_project.py:4:1: E302 expected 2 blank lines, found 1 ./tests/test_my_project.py:7:1: E302 expected 2 blank lines, found 1
如何将Flake 8添加到git钩子中?
IDE中的红色标记有时很容易忽略。也很容易忘记跑步flake8
在提交代码之前发出命令。这就是为什么我们有吉特钩。我们可以将Flake8添加到钩子列表中,因此它将自动使用Linter检查我们的代码。
要做到这一点,打开.pre-commit-config.yaml
并增加如下:
- repo: https://gitlab.com/pycqa/flake8rev: 3.8.3hooks:- id: flake8
格外注意rev
排队。我自己在这里添加了版本。为了弄清楚我们目前使用的Flake8版本,我打开了pyproject.toml
,找到了Flake8的版本,并如前所述将其放入预提交配置文件中。
记住,就像我们问的pre-commit
为了保持最新版本,它将将Flake8更新为最新版本。但是由于我们已经使用了最新版本的Linter,这里不会做任何额外的事情。pre-commit
将下载此版本的Flake8,因为它在单独的环境中运行检查。这意味着我们现在基本上有两个版本的版本,我们应该确保它们实际上是相同的版本。通常更新到最新版本不应该是一个问题,但如果是,建议关闭自动更新pre-commit
.
当我们更改配置文件时,让我们分阶段进行:
git add .pre-commit-config.yaml
并承诺:
git commit -m 'Add Flake8 to git hooks'
Trim Trailing Whitespace.................................................Passed Fix End of Files.........................................................Passed Check Yaml...............................................................Passed Check for added large files..............................................Passed flake8...............................................(no files to check)Skipped [master 1d25c9f] Add Flake8 to git hooks1 file changed, 4 insertions(+)
让我们试着跑pre-commit
再次手动查看它是如何捕获Flake8的:
pre-commit run --all-files
Trim Trailing Whitespace.................................................Passed Fix End of Files.........................................................Passed Check Yaml...............................................................Passed Check for added large files..............................................Passed flake8...................................................................Failed - hook id: flake8 - exit code: 1tests/test_my_project.py:4:1: E302 expected 2 blank lines, found 1 tests/test_my_project.py:7:1: E302 expected 2 blank lines, found 1
不要急于修复这个错误以满足连接器的要求。计算机已经发现了错误。如果它已经完成了,那么自动修复这个错误不是很棒吗?
用黑色格式化代码
为什么要用黑色格式化代码?
每个人都以自己的风格编写代码。即使在Python(它迫使您缩进代码块)上,也很可能以不同的方式编写相同的东西。
有时候,只要看一看代码的某个部分,你就可以知道是谁写的。如果不同的人以自己的风格触摸相同的代码并编写不同的代码,该怎么办?看上去有点丑。
我们怎样才能防止?当然,我们可以在代码评审期间进行争论。这可以显著减缓合并此类拉请求的速度。另外,关于风格的争论也是一个品味的问题。到头来,人们会争论代码的外观,而不是关注代码的实际功能。
此外,如果整个项目的代码看起来都是一样的,就像由一个人编写的那样,那不是很好吗?
有一个解决方案,叫做黑色 .
黑色以自己的风格格式化代码,因此它看起来是一致的。您可以在“黑色”中自定义的东西非常少,因此即使在这种情况下也没有争论的余地。拿着它用它就行了。毕竟,像PEP 8和Black这样的东西是为了在一种风格上达成一致,所以不要再争论了。
具有讽刺意味的是,Black违反了PEP 8的线路长度规则。有一件事,PEP 8告诉我们,最大行距不应该超过79个字符。它深入到IBM穿孔卡和UNIX终端的历史中。PEP 8是2001年编写的,此后情况发生了变化。人们开始质疑这条规则。“我不读UNIX终端的代码”-他们说。“我有27台”显示器是有原因的,“他们说。不过这有个问题。有些人用13”笔记本电脑的代码工作。而查看两个文件的差异为每行79字符的最大值变得非常方便。否则,您必须水平滚动,这对于处理代码来说不是很好。这就是为什么我仍然认为79个字符规则应该在那里。
是的,虽然PEP 8是在2001年创建的,但是它收到了一些更新从那以后,每行规则有79个字符从未改变。
谢天谢地,这是一个选项,布莱克允许我们调整。
如何安装黑色?
在VS代码中,在我们的项目中打开一些Python文件。就我而言,我test_my_project.py
那个Flake 8在抱怨。⇧⌘P并开始键入“Format”,然后选择“Format Document”。
它会问你想使用哪个格式化程序。
点击“使用黑色”。
VS代码将检测到我们使用诗歌,并将安装黑色为我们自动。
或者,您可以手动安装它:
poetry add --dev black --allow-prereleases
--allow-prereleases
选项在这里,因为布莱克实际上还在贝塔2021年。最初,2019年的发行计划是在这种状态下的最后一个版本,但这就是它的现状。许多生产和开放源码项目已经默认使用它来格式化代码,因此假设Black相对稳定是相当安全的。
要配置Black,让我们打开pyproject.toml
并增加以下部分:
[tool.black] line-length = 79 target-version = ['py38'] include = '\.pyi?$' exclude = '''(/(\.eggs # exclude a few common directories in the| \.git # root of the project| \.hg| \.mypy_cache| \.tox| \.venv| _build| buck-out| build| dist)/| foo.py # also separately exclude a file named foo.py in# the root of the project ) '''
这里最重要的部分是我们把最大线长设为79。
另外,如果您使用Python的其他版本,请确保更新,但要反复检查它是否受Black支持这里 .
为了使之与Black一起工作,我们还必须在Flake8中抑制一些错误。为此,我们必须创建setup.cfg
文件,它是Flake8的一个配置文件,并将以下内容放入其中:
[flake8] extend-ignore = E203
怎么用黑?
黑色的用法相当简单。只要运行它,它就格式化代码:
black .
reformatted /projects/my-project/my_project/__init__.py reformatted /projects/my-project/tests/test_my_project.py All done! :sparkles: :cake: :sparkles: 2 files reformatted, 2 files left unchanged.
还记得Flake 8抱怨没有新台词吗?如果我们现在运行我们的Git钩子,一切都会好起来的。
pre-commit run --all-files
Trim Trailing Whitespace.................................................Passed Fix End of Files.........................................................Passed Check Yaml...............................................................Passed Check for added large files..............................................Passed flake8...................................................................Passed
如何将黑色添加到Git钩子中?
和版本8一样,自动运行Black也很好,所以我们不必费心。让我们在.pre-commit-config.yaml
- repo: https://github.com/psf/blackrev: 20.8b1hooks:- id: black
我们跑吧pre-commit run --all-files
再来一次。我们可以看到它下载了Black并使用它:
[INFO] Initializing environment for https://github.com/psf/black. [INFO] Installing environment for https://github.com/psf/black. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... Trim Trailing Whitespace.................................................Passed Fix End of Files.........................................................Passed Check Yaml...............................................................Passed Check for added large files..............................................Passed flake8...................................................................Passed black....................................................................Passed
我不会描述保存对GIT的更改。流程与Flake8相同。
替代方案:yapf-Https://github.com/google/yapf
奖金
您可以在VS代码中添加标尺,这样就有一条垂直线显示了79个字符的边沿。
打开settings.json
在……里面.vscode
目录并添加以下内容:
"[python]": {"editor.rulers": [72, 79]}
这将只为Python添加统治者。72个字符用于文档字符串。
用Mypy进行静态键入
为什么在Python中使用静态类型检查器?
类型战争始于70年代。IBM与Smalltalk对抗Sun和Java。众所周知,强类型Java赢了,虽然Smalltalk是动态类型化语言,但由于发展迅速,一些公司认为它是一种竞争优势。当然,类型减少了bug和运行时错误的数量,这也可以通过100%的测试覆盖率来解决(如鲍勃叔叔声称,这是Python成功的原因之一)。但是,我们不要忘记,并不是所有的项目都有100%的覆盖率。
但我们能拥有最好的两个世界吗?我们可以通过快速的软件开发来实现类型安全吗?我想和Mypy一起我们可以。Mypy是一个静态代码分析工具,它确保代码是类型安全的。这个项目变得非常有价值,以至于Python创建者GuidovanRossum向Python添加了类型注释,并加入了Mypy开发。使用类型注释还有助于IDE提供更好的代码完成。更重要的是,类型注释也使代码对人类来说更加可读性。
如何安装类型
在VS代码中,您可以编辑settings.json
文件在.vscode
目录。集"python.linting.mypyEnabled": true
。之后,打开项目中的任何Python文件,例如math.py
。VS代码将检测到Mypy尚未安装。
单击安装,它将自动安装它与诗歌。
或者,您可以手动安装Mypy:
poetry add --dev mypy
如何使用类型?
现在,我们可以尝试在我们的小项目上运行这个工具:
mypy .
Success: no issues found in 4 source files
到目前为止,我们甚至不需要对代码进行任何更改,Mypy会自动检测类型来运行检查。
但是,正如我们前面提到的,类型注释有助于我们更好地理解代码,并使IDE提供更好的代码完成,因此让我们利用这一点。
打开setup.cfg
归档并添加以下内容:
[mypy] follow_imports = silent strict_optional = True warn_redundant_casts = True warn_unused_ignores = True disallow_any_generics = True check_untyped_defs = True no_implicit_reexport = True disallow_untyped_defs = True ignore_missing_imports = True
这里最重要的一行是disallow_untyped_defs = True
。它迫使您使用类型定义函数。对于现有的遗留项目,您可能会禁用它,但是当我们创建一个新项目时,确保永远不会忘记添加类型注释是有益的。
您可能希望禁用Mypy进行测试。只需添加以下配置:
[mypy-tests.*] ignore_errors = True
为了更好的兼容性,有各种插件为Mypy。例如,如果计划使用pydantic
对于数据验证和序列化,配置文件如下所示:
[mypy] plugins = pydantic.mypyfollow_imports = silent strict_optional = True warn_redundant_casts = True warn_unused_ignores = True disallow_any_generics = True check_untyped_defs = True no_implicit_reexport = True disallow_untyped_defs = True ignore_missing_imports = True[pydantic-mypy] init_forbid_extra = True init_typed = True warn_required_dynamic_aliases = True warn_untyped_fields = True
以下是添加新配置后的输出:
my_project/math.py:1: error: Function is missing a type annotation Found 1 errors in 1 files (checked 4 source files)
此外,VS代码使用Mypy作为链接并标记不正确的部分:
为了修复它,让我们将类型注释添加到我们的函数中:
from numbers import Real from typing import Uniondef multiply_two_numbers(a: Union[int, Real], b: Union[int, Real]) -> Union[int, Real]:return a * b
正如我们所看到的,函数定义太长了。通过按下⇧⌥F,VS代码用黑色格式化代码,使其适合每行79个字符:
from numbers import Real from typing import Uniondef multiply_two_numbers(a: Union[int, Real], b: Union[int, Real] ) -> Union[int, Real]:return a * b
提交更改:
git commit -m 'Add Mypy'
如何将类型添加到git钩子中?
显然,我们希望确保Mypy在提交代码之前运行。添加以下内容.pre-commit-config.yaml
:
- repo: https://github.com/pre-commit/mirrors-mypyrev: v0.782hooks:- id: mypyadditional_dependencies: [pydantic] # add if use pydantic
当我们跑的时候pre-commit run --all-files
它为预提交安装Mypy并运行检查:
[INFO] Installing environment for https://github.com/pre-commit/mirrors-mypy. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... Trim Trailing Whitespace.................................................Passed Fix End of Files.........................................................Passed Check Yaml...............................................................Passed Check for added large files..............................................Passed flake8...................................................................Passed black....................................................................Passed mypy.....................................................................Passed
用ISTERT分类进口
最后一件事:进口。
为什么要分类进口?
PEP 8指定导入应该按照以下顺序排序:标准库、第三方、本地。此外,我们希望进口产品美观、人性化。
这是一个工具。相会isort
代表“进口分类”。这是一个来自官方网站的例子去了解它。
之前:
from my_lib import Objectimport osfrom my_lib import Object3from my_lib import Object2import sysfrom third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14import sysfrom __future__ import absolute_importfrom third_party import lib3
之后:
from __future__ import absolute_importimport os import sysfrom third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8,lib9, lib10, lib11, lib12, lib13, lib14, lib15)from my_lib import Object, Object2, Object3
好多了,不是吗?
如何安装、使用和添加isort到git挂钩?
VS代码(带有Python扩展)使用isort
在内部,因此不需要额外的配置。如果您不打算从命令行使用它,则甚至不需要单独安装它,因为pre-commit
将所有依赖项安装到它自己的独立环境中。
但如果你打算用isort
除了VS代码和pre-commit
,下面是如何安装它:
poetry add --dev isort
为了使它正确地与黑色一起工作,我们应该在pyproject.toml
:
[tool.isort] multi_line_output = 3 include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true line_length = 79
在VS代码中,⇧⌘P,然后开始键入“排序导入”。VS代码将显示:
或者,如果安装了它,请在项目根目录中运行:
isort .
Skipped 2 files
作为最后一步,让我们将其添加到.pre-commit-config.yaml
:
- repo: https://github.com/PyCQA/isortrev: 5.4.2hooks:- id: isort
看它的效果pre-commit run --all-files
:
Trim Trailing Whitespace.................................................Passed Fix End of Files.........................................................Passed Check Yaml...............................................................Passed Check for added large files..............................................Passed flake8...................................................................Passed black....................................................................Passed mypy.....................................................................Passed isort....................................................................Passed
快轨
下面是如何在几分钟内创建一个完全配置的新项目(假设您有pyenv
和poetry
已安装)。
poetry new my-project; cd my-project; ls pyenv local 3.9.2 poetry env use python poetry add --dev pytest-cov pre-commit flake8 mypy isort poetry add --dev --allow-prereleases black poetry shell code .
将配置添加到pyproject.toml
:
[tool.isort] multi_line_output = 3 include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true line_length = 79[tool.black] line-length = 79 target-version = ['py38'] include = '\.pyi?$' exclude = '''(/(\.eggs # exclude a few common directories in the| \.git # root of the project| \.hg| \.mypy_cache| \.tox| \.venv| _build| buck-out| build| dist)/| foo.py # also separately exclude a file named foo.py in# the root of the project ) '''
创造setup.cfg
:
[flake8] extend-ignore = E203[mypy] follow_imports = silent strict_optional = True warn_redundant_casts = True warn_unused_ignores = True disallow_any_generics = True check_untyped_defs = True no_implicit_reexport = True disallow_untyped_defs = True ignore_missing_imports = True[mypy-tests.*] ignore_errors = True
创造.pre-commit-config.yaml
.
repos: - repo: https://github.com/pre-commit/pre-commit-hooksrev: v3.4.0hooks:- id: trailing-whitespace- id: end-of-file-fixer- id: check-yaml- id: check-added-large-files - repo: https://gitlab.com/pycqa/flake8rev: 3.8.4hooks:- id: flake8 - repo: https://github.com/psf/blackrev: 20.8b1hooks:- id: black - repo: https://github.com/pre-commit/mirrors-mypyrev: v0.812hooks:- id: mypyadditional_dependencies: [pydantic] # add if use pydantic - repo: https://github.com/PyCQA/isortrev: 5.7.0hooks:- id: isort
echo '.coverage' > .gitignore echo '.vscode/\n.idea/' >> .gitignore curl -s https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore >> .gitignore git init -b main git add . git commit -m 'Initial commit' pre-commit install pre-commit autoupdate pre-commit run --all-files pre-commit run --all-files
结语
我们走了很远的路。如果你从一开始就做到了,恭喜你。我知道那可能是超级压倒性的。做所有这些工作的目的是建立一个新的项目一次,并忘记它很长一段时间。对于任何进一步的项目,它将是非常迅速的,我保证。只需跳到快速通道部分,然后只需几分钟就可以设置所有必要的组件。现在,是时候用一些实际的代码弄脏我们的手了。
2021年新项目的Python最佳实践相关推荐
- python最佳实践指南试题_8.1. 关于这份指南
与 Tcl.Perl.Ruby.Scheme 以及 Java 类似,Python 是一门用途广泛的高级编程语言.它的一些关键特性有: 语法清晰.可读性极佳 Python 的设计哲学着眼于可读性,它以缩 ...
- python最佳实践笔记
本文为阅读Python最佳实践指南后的心得体会 结构 README.rst LICENSE setup.py requirements.txt sample/__init__.pycore.pyhel ...
- Python 最佳实践
前言 对我来说,以前每次面试是我审视自己,检验自己的一种方式.每次准备面试,以及被面试官问住的时候才会发现,其实我python我学的还不够好.工作中也是,可以从其他的同事那里获得成长.但是我今天说的是 ...
- 硅谷python_来自硅谷的Python最佳实践指南 | 极客时间
这几年,学 Python 的程序员的确越来越多了,甚至不少人把 Python 当作第一语言来学习.也难怪,Python 的优点太多了,它语言简洁.开发效率高.可移植性强,并且可以和其他编程语言(比如 ...
- python最佳实践指南试题_Python最佳实践指南 阅读笔记
创建将0到19连接起来的字符串1 2 3 4 5 6 7 8nums = [] for n in range(20): nums.append(str(n)) print "".j ...
- 30个Python最佳实践和技巧,你值得拥有~
全文共8869字,预计学习时长26分钟 来源:Pexels 1. 使用Python3 温馨提示:官方宣布自2020年1月一日起将不再支持Python2.这份指南里的大多数例子也只在Python3中适用 ...
- 阿里云S级新游上云最佳实践
文丨木久,阿里云弹性计算产品解决方案架构师 摘要:游戏一直以来是互联网领域的一大热门行业,随着移动互联网的兴起,手机和Pad的普及,游戏从早期PC时代的页游.端游,逐渐发展到手游占据主要趋势.近几 ...
- 3个适合初学者的Python最佳实践,值得拥有!
全文共2041字,预计学习时长6分钟 来源:Pexels 我们常常分享编程其实很简单的文章,给大家树立信心. 如果只是编写简单的程序,如果你只是想马上完成,一天的时间即可完成. 但如果你想很快地编写复 ...
- 新零售行业搜索最佳实践
简介:本文通过新零售客户案例带大家了解零售电商.生鲜电商线上业务搜索中的行业特性,以及如何通过开放搜索电商增强版解决方案构建智能搜索服务,快速实现各项指标的提升,为业务带来了更多新的机会. 客户背景 ...
最新文章
- Dataset之LSUN:LSUN数据集的下载使用教程
- php $interval,如何在PHP中使用setInterval?
- linux内核双向循环队列,读书笔记之linux内核设计与实现(2)进程调度
- 解决Maven工程中报 Missing artifact jdk.tools:jdk.tools:
- 只有ajax会跨域吗_ajax解决跨域
- 【186天】黑马程序员27天视频学习笔记【Day15-上】
- python统计词频瓦尔登湖_1.5 python文件操作
- linux以命令行下配置连接wlan无线网卡
- U8系统UFO报表无法打印
- CSS揭破实用窍门总结
- java的诞生詹姆斯·高斯林
- 如何清除 浏览器-hao123的绑定
- 深度学习进阶之路 - 从迁移学习到强化学习
- unsteady_rel_perm案例学习
- 防止关闭windows
- 真c++ 从二叉树到红黑树(3)之二叉搜索树BST
- GitHub Desktop 上实现项目的回滚操作,详细介绍
- Hack the box靶机 Admirer
- 计算机考研复试-离散数学
- 《30天自制操作系统》day1
热门文章
- [Trans 系列之一]TransE算法(Translating Embedding)
- 计算机科学个人陈述中文,计算机专业个人陈述二十(计算机科学)
- 电子计算机快速算法,序列产生的快速算法
- 打印html java 清晰度_java 利用jsp打印html页面
- 强化学习代码实操和讲解(三)
- 经典 Fuzzer 工具 AFL 模糊测试指南
- 使用python实现mysql测试数据的准备(大批量导入数据)
- 使用tortoisegit clone通过ssh clone远程库:invalid gitfile format: D:\Program Files\TortoiseGit\bin\Tortois“
- ⚡豆瓣告诉你《扫黑风暴》如何【短评爬取+词云】 ⚡
- 在线支付支付宝(一)之开发者账号申请