Python的開發必備:如何建立一個優秀的專案工程環境

程式設計只為發表於2019-09-04

在程式開發時候一套好的開發環境和工具棧,可以幫我們極大的提高開發的效率,避免把大量時間浪費在周邊瑣事上。

本文以Python的為例,教大家如何快速打造優秀的Python的專案開發環境:內容涵蓋了模組依賴管理,程式碼風格管理,除錯測試管理和Git版本管理,使用git hook做專案規範檢查等。

pipx

Pipx是一款跨平臺的Python環境隔離管理工具,可以在支援在Linux,Mac OS和Windows上執行.Pipx預設在是個人使用者下建立虛擬Python環境,並以此建立實現完全隔離的Python執行環境。安裝pipx需要Pthon 3.6及以上版本:

<span style="color:#444444">python3 -m pip  <span style="color:#333333"><strong>install </strong></span> <span style="color:#888888">--user pipx </span>
python3 -m pipx ensurepath 
</span>

升級Pipx使用:

<span style="color:#444444"><span style="color:#333333"><strong>python3</strong></span>  -m pip install -U pipx 
</span>

包依賴管理pipenv

Pipenv會自動為你的專案建立和管理虛擬環境,以pipfile檔案方式方式管理專案的依賴包,支援包的安裝和解除安裝。和requirements.txt不同,pipfile是TOML格式,支援開發環境與正式環境,還可以使用Pipfile.lock鎖定環境版本.pipxenv的安裝可以使用pipx:

<span style="color:#444444"><span style="color:#333333"><strong>pipx</strong></span>  安裝pipenv 
</span>

有些發行版也是可以直接通過其包管理器安裝的:

比如MacOS的可以下可以使用:

<span style="color:#444444"><span style="color:#333333"><strong>brew</strong></span>  安裝pipenv 
</span>

一個pipfile的示例如下:

Pipfile.lock的示例部分如下:

程式碼風格

程式碼格式化黑色

程式碼格式的統一不光可以給我們一個愜意的程式碼格式,而且可以避免由於開發人員之間的程式碼風格差異導致的溝通和協作問題。

黑就是用來格式化的Python程式碼的程式。它可以自動幫我們對程式碼格式進行調整和統一,提高程式碼效率和可讀性。而且通過黑色減小程式碼風格的差異,可以極大提高團隊進行程式碼審查的效率。

一個黑色格式化示例如下:

原始程式碼:

<span style="color:#444444"><span style="color:#333333"><strong>def </strong></span> <span style="color:#880000"><strong>very_important_function </strong></span>(template:str,* variables,file:os.PathLike,engine:str,header:bool = True,debug:bool = False): 
<span style="color:#880000">“”將`variables`應用於`template`並寫入`file ` “”” </span> 
<span style="color:#333333"><strong>與</strong></span>  開啟(檔案, <span style="color:#880000"> 'W' </span>) <span style="color:#333333"><strong>為</strong></span>  F: 
... 
</span>

格式化後的程式碼:

<span style="color:#444444"><span style="color:#333333"><strong>def </strong></span> <span style="color:#880000"><strong>very_important_function </strong></span>( 
模板:str, 
*變數, 
file:os.PathLike, 
引擎:str, 
header:bool = True, 
debug:bool = False, 
): 
<span style="color:#880000">“” “適用`variables`到`template`並寫入`file`。” “” </span> 
<span style="color:#333333"><strong>與</strong></span>  開啟(檔案, <span style="color:#880000"> “W” </span>) <span style="color:#333333"><strong>為</strong></span>  F: 
... 
</span>

isort美化進口部分程式碼

Python開發中經常需要匯入第三方的模組,往往這部分程式碼混亂不堪,使用isort可以則可以美化這部分的程式碼.isort可以按字母表順序對import進行排序,自動分成多個部分。

我們可以使用pipenv安裝black和isort:

<span style="color:#444444"><span style="color:#333333"><strong>pipenv</strong></span>  安裝黑色isort -dev 
</span>

isort的效果示例,可以看下面的動圖:

黑色和isort同時使用時,兩者預設配置不相容,我們需要覆蓋isort配置,優先以黑色的格式化為準。可以通過setup.cfg檔案並添如下配置來完成該任務。

<span style="color:#444444"><span style="color:#880000"><strong>[isort] </strong></span> 
multi_line_output = <span style="color:#880000">3 </span> 
include_trailing_comma = <span style="color:#78a960">True </span> 
force_grid_wrap = <span style="color:#880000">0 </span> 
use_parentheses = <span style="color:#78a960">True </span> 
line_length = <span style="color:#880000">88</span> 
</span>

flake8程式碼風格檢測

Flake8可以用來確保程式碼遵循PEP8中定義的標準的Python程式設計約定,是Python的官方輔助程式碼風格檢測工具,lake8檢查規則靈活,支援整合額外外掛(比如VIM,昇華,PyCharm,VSC等都有其相關外掛) ,擴充套件性強。

其安裝也可以使用pipenv:

<span style="color:#444444"><span style="color:#333333"><strong>pipenv</strong></span>  安裝flake8 -dev 
</span>

flake8的使用示例如下:

flake8 example.py的檢查結果:

flake8預設會忽略一些約定(E,F),如果我們檢查所有約定:

flake8 - 選擇E,F example.py,結果:

和isort一樣,為了配合相容黑色,需要在setup.cfg中額外配置:

<span style="color:#444444"><span style="color:#880000"><strong>[flake8] </strong></span> 
ignore  = E203,E266,E501,W503 
 max-line-length  =  <span style="color:#880000">88 </span> 
max-complexity  =  <span style="color:#880000">18 </span> 
select  = B,C,E,F,W,T4 
</span>

mypy靜態型別

Mypy是Python中的可選靜態型別檢查器,可以用結合動態(或 “鴨子”)型別和靜態型別優點其他程式碼的效能。通過Mypy將Python中的動態型別便捷性和表現力的優勢與靜態型別強系統和編譯時型別檢查相結合,並且生成原生程式碼,支援通過Python VM執行,可以沒有執行時開銷的高效能執行。在Python中使用靜態型別好處有:

可以使程式更易於理解和維護;

可以幫助編譯時除錯和發現錯誤,減少測試和除錯。

可以在程式碼部署到生產環境之前就可以找到難以捕捉的錯誤。

可以使用pipenv直接安裝Mypy:

<span style="color:#444444"><span style="color:#333333"><strong>pipenv</strong></span>  安裝mypy -dev 
</span>

mypy動態型別和靜態型別一個示例如下:

專案配置

預設情況下,Mypy會遞迴檢查所有型別註釋的匯入,這會導致庫不包含這些註釋時出錯。需要修改mypy配置僅檢查當前程式碼執行,並忽略沒有型別註釋的匯入模組。這也可以在設定。 CFG中設定:

<span style="color:#444444"><span style="color:#880000"><strong>[mypy] </strong></span> 
files =專案,test 
 ignore_missing_imports = <span style="color:#78a960">true</span> 
</span>

程式碼測試

程式開發中,除了寫程式碼外,另外一個重要的部分是單元測試.Python測試方面我們要介紹的工具有pytest。

可以使用pipenv新增測試工具包及擴充套件:

<span style="color:#444444">pipenv  <span style="color:#333333"><strong>安裝</strong></span>  pytest pytest-cov  <span style="color:#888888">--dev </span>
</span>

。Pytest框架可以讓編寫小測試變得容易,而且支援以擴充套件的方式提供更加複雜的功能下面是pytest網站的一個簡單示例:

<span style="color:#444444"><span style="color:#888888">#test_sample.py  </span>
<span style="color:#333333"><strong>def </strong></span> <span style="color:#880000"><strong>inc </strong></span>(x)的內容: 
<span style="color:#333333"><strong>return</strong></span>  x +  <span style="color:#880000">1 </span> 
<span style="color:#333333"><strong>def </strong></span> <span style="color:#880000"><strong>test_answer </strong></span>(): 
<span style="color:#333333"><strong>assert</strong></span>  inc(<span style="color:#880000">3</span>)==  <span style="color:#880000">5</span> 
</span>

通過以下命令測試

<span style="color:#444444">pipenv  <span style="color:#333333"><strong>執行</strong></span> pytest 
</span>

結果如下:

pytest冠狀病毒是pytest的單元測試行覆蓋率的外掛.pytets冠狀病毒的測試結果示例如下:

pytest還有很多的擴充套件外掛:

pytest-cov:單元測試覆蓋率報告

pytest-django:對Django框架的單元測框架

pytest-ASYNCIO:對ASYNCIO的支援

pytest-twisted:對扭框架的單元測框架

pytest-instafail:傳送錯誤時報告錯誤資訊

pytest-bdd測試驅動開發工具

pytest-konira測試驅動開發工具

pytest-timeout:支援超時功能

pytest-pep8:支援PEP8檢查

pytest-flakes:結合pyflakes進行程式碼檢查

更多外掛可以檢視github pytest-dev組織下的專案。

專案配置

專案中,所有的測試都應該放在測試目錄中,我需要給setup.cfg新增配置:

<span style="color:#444444"><span style="color:#880000"><strong>[tool:pytest] </strong></span> 
testpaths = test 
</span>

單元覆蓋率的專案配置需要建立一個新檔案.coveragerc返回應用程式程式碼的覆蓋率統計資訊,配置示例如下:

<span style="color:#444444">[跑] 
source =專案 
[報告] 
exclude_lines = 
<span style="color:#333333"><strong>pragma</strong></span>:  <span style="color:#333333"><strong>沒有</strong></span>  封面 
 <span style="color:#333333"><strong>def</strong></span>  __repr__ 
 <span style="color:#333333"><strong>如果</strong></span> <span style="color:#333333"><strong>self</strong></span> \ .debug 
 <span style="color:#333333"><strong>引發</strong></span>  AssertionError 
 <span style="color:#333333"><strong>引發</strong></span>  NotImplementedError 
 <span style="color:#333333"><strong>如果為</strong></span> <span style="color:#880000">0</span>: 
 <span style="color:#333333"><strong>if</strong></span>  __name__ == .__ main__: 
</span>

然後再工程中執行一下命令,測試專案的覆蓋率

<span style="color:#444444">pipenv  <span style="color:#333333"><strong>執行</strong></span> pytest --cov --cov-fail-under = 100 
</span>

如果程式程式碼的測試覆蓋率低於100%時,就會報錯。

Git pre-commit hook規範檢查

Git hook可以讓我們在提交或推送時執行檢查指令碼,指令碼可以配置對專案映象測試或者規範性檢查。執行指令碼。我們可以配置pre-commit hook允許輕鬆配置這些鉤子,下面.pre-commit-config。 YAML配置示例可以幫我們自動做程式碼規範化,包括isort檢查,黑檢查,flake8檢查,mypy靜態型別檢查,pytest測試,pytest冠狀病毒測試覆蓋率檢查:

<span style="color:#444444"><span style="color:#880000">repos:</span>  
-  <span style="color:#880000">repo:</span>  local 
 <span style="color:#880000">hooks:</span>  
-  <span style="color:#880000">id:</span>  isort 
 <span style="color:#880000">name:</span>  isort 
 <span style="color:#880000">階段:</span>  [commit] 
 <span style="color:#880000">語言:</span>  系統 
 <span style="color:#880000">條目:</span>  pipenv run isort 
 <span style="color:#880000">型別:</span>  [python] 
-  <span style="color:#880000">id:</span>  黑 
 <span style="color:#880000">名:</span>  黑 
 <span style="color:#880000">階段:</span>  [commit] 
 <span style="color:#880000">語言:</span>  系統 
 <span style="color:#880000">入口:</span>  pipenv執行黑色 
 <span style="color:#880000">型別:</span>  [python] 
-  <span style="color:#880000">id:</span>  flake8 
 <span style="color:#880000">name:</span>  flake8 
 <span style="color:#880000">階段:</span>  [commit] 
 <span style="color:#880000">語言:</span>  系統 
 <span style="color:#880000">入口:</span>  pipenv run flake8 
 <span style="color:#880000">型別:</span>  [python] 
 <span style="color:#880000">exclude:</span>  setup.py 
-  <span style="color:#880000">id:</span>  mypy 
 <span style="color:#880000">name:</span>  mypy 
 <span style="color:#880000">階段:</span>  [commit] 
 <span style="color:#880000">語言:</span>  系統 
 <span style="color:#880000">入口:</span>  pipenv run mypy 
 <span style="color:#880000">types:</span>  [python] 
 <span style="color:#880000">pass_filenames:</span> <span style="color:#78a960">false</span>  
-  <span style="color:#880000">id:</span>  pytest 
 <span style="color:#880000">name:</span>  pytest 
 <span style="color:#880000">階段:</span>  [commit] 
 <span style="color:#880000">語言:</span>  系統 
 <span style="color:#880000">入口:</span>  pipenv run pytest 
 <span style="color:#880000">型別:</span>  [蟒蛇] 
-  <span style="color:#880000">id:</span>  pytest-cov 
 <span style="color:#880000">name:</span>  pytest 
 <span style="color:#880000">階段:</span>  [push] 
 <span style="color:#880000">語言:</span>  系統 
 <span style="color:#880000">入口:</span>  pipenv run pytest --cov --cov-fail-under = <span style="color:#880000">100 </span> 
<span style="color:#880000">種型別:</span>  [python] 
</span>

如果你需要跳過這些鉤子,你可以執行git commit --no-verify或git push --no-verify

18.11自動建立專案

上面我們提到的Python專案應該具備的工具集和配置,可以將其作為模版.cookiecutter的模版定義範例如下:

<span style="color:#444444">cookiecutter.json 
{ 
<span style="color:#880000">“full_name”</span>:  <span style="color:#880000">“Chongchong”</span>, 
 <span style="color:#880000">“email”</span>:  <span style="color:#880000">“chongchong@ijz.me”</span>, 
 <span style="color:#880000">“project_name”</span>:  <span style="color:#880000">“Python-Practice”</span>, 
 <span style="color:#880000">“repo_name”</span>:  <span style="color:#880000">“”</span> Python-Practice  <span style="color:#888888">“,  </span>
<span style="color:#880000">”project_short_description“</span>:  <span style="color:#880000">”簡單的Python開發練習示例。“</span>, 
 <span style="color:#880000">”release_date“</span>:  <span style="color:#880000">”2019-09-02“</span>, 
 <span style="color:#880000">”年“</span>:  <span style="color:#880000">”2019“</span>, 
 <span style="color:#880000">”版本“</span>:  <span style="color:#880000">”0.0.1“</span> 
} 
</span>

然後使用18.11自動生成整改工程:

<span style="color:#444444">pipx <span style="color:#333333"><strong>執行</strong></span> cookiecutter   Python-Practice 
 cd Python-Practice 
git init 
</span>

安裝依賴項

<span style="color:#444444">pipenv  <span style="color:#333333"><strong>安裝</strong></span> <span style="color:#888888">--dev </span>
</span>

執行pre-commit和pre-push hook:

<span style="color:#444444">pipenv  <span style="color:#333333"><strong>執行</strong></span> pre-commit install -t pre-commit 
 pipenv  <span style="color:#333333"><strong>run </strong></span> pre-commit install -t pre-push 
</span>

總結

本文我們介紹了在Python的專案開發時候必須要具備的一些開發測試檢查工具。通過這些可以自動生成的Python專案,程式碼風格檢查,程式碼測試等操作,可以幫助我們打造一個高效完美的Python的開發環境。

相關文章