转载本文请联系Python中文社区公众号。如果你像我一样,偶尔会写一个有用的小python实用程序并想与你的同事分享。最好的方法是制作一个Python包:它易于安装并且无需复制。您可能认为创建包很麻烦。事实上,情况已不再如此。我将用这个分步指南进行解释。它只是三个主要步骤(以及一系列可选步骤),辅以几个GitHub链接。1.初始化我们将创建podsearch-一个用于在iTunes中搜索播客的实用程序。让我们创建一个目录和一个虚拟环境:$mkdirpodsearch$cdpodsearch$python3-mvenvenv$.env/bin/activate定义一个最小的包结构:.├──.gitignore└──podsearch└──__init__.py"""让'sfindsomepodcasts!"""__version__="0.1.0"defsearch(name,count=5):"""Searchpodcastbyname."""raiseNotImplementedError()2.测试包在Python中创建包曾经是一项繁琐的任务。幸运的是,现在有一个很棒的flit(https://flit.readthedocs.io/en/latest/)小程序可以简化一切。让我们安装它:pipinstallflit并创建包描述:$flitinitModulename[podsearch]:Author[AntonZhiyanov]:Authoremail[m@antonz.org]:Homepage[https://github.com/nalgeon/podsearch-py]:Choosealicense(参见http://choosealicense.com/formoreinfo)1.MIT-simpleandpermissive2.Apache-explicitlygrantspatentrights3.GPL-ensuresthatcodebasedonthisissharedwiththesameterms4.Skip-choosealicenselaterEnter1-4[1]:1Writtenpyproject.toml;editthatfiletoaddoptmltionalextrainfopy.pyprojectcreated元数据文件。它已经拥有将包发布到公共存储库-PyPI所需的一切。注册TestPyPi(测试存储库)和PyPI(主存储库)。它们是完全独立的,因此您需要两个帐户。在~/.pypirc中设置对存储库的访问:并将包发布到测试存储库:$flitpublish--repositorypypitestFound4filestrackedingit...Packageisathttps://test.pypi.org/project/podsearch/完成!该包在TestPyPi上可用。3.公开包让我们改进代码,使其真正搜索播客:#...SEARCH_URL="https://itunes.apple.com/search"@dataclassclassPodcast:"""Podcastmetadata."""id:strname:strauthor:strurl:strfeed:Optional[str]=Nonecategory:Optional[str]=Noneimage:Optional[str]=Nonedefsearch(name:str,limit:int=5)->List[Podcast]:"""Searchpodcastbyname."""params={"term":name,"limit":limit,"media":"podcast"}response=_get(url=SEARCH_URL,params=params)return_parse(response)并发布到主存储库-PyPI。仅当您的包中有有用的代码时才执行此步骤。不要分发无效的包和存根。flitpublish已发布!有时间与同事分享。为了使包易于使用,我建议再执行几个步骤。A.Readme和changelog没有人喜欢写文档。但是,人们不太可能在没有文档的情况下安装您的包,因此我们需要添加README.md和CHANGELOG.md。README.mdCHANGELOG.md将README添加到pyproject.toml,以便PyPI在包页面上显示它:description-file="README.md"还指定支持的最低Python版本:requires-python=">=3.7"在__init__中更新版本。py和publishpackageviaflitpublish:B.Lintersandtests让我们考虑格式化(黑色)、测试覆盖率(coverage)、代码质量(flake8、pylint、mccabe)和静态分析(mypy)。我们会通过tox处理一切。$pipinstallblackcoverageflake8mccabemypypylintpytesttox在tox.ini中创建tox配置:[tox]isolated_build=Trueenvlist=py37,py38,py39[testenv]deps=blackcoverageflake8mccabemypypylintpytestcommands=blackpodsearchflake8podsearchpylintpodsearchmypypodsearchcoverageerasecoveragerun--include=podsearch/*-mpytest-racoveragereport-mtox.ini并运行所有检查:$tox-epy39...py39run-test:commands[0]|blackpodsearchAlldone!...py39run-test:commands[2]|pylintpodsearchYourcodehasbeasratedat10.00/10(previousrun:10.00/10,+0.00)...py39run-test:commands[6]|coveragereport-mTOTAL100%...py39:commandssucceededcongratulations:)linters测试通过,测试也通过,覆盖率100%。C.云构建每个可靠的开源项目在每次提交后都会进行云测试,所以我们也会这样做。自述文件中的漂亮徽章是一个不错的附加效果。让我们使用GitHubActions构建项目,使用Codecov检查测试覆盖率,并使用CodeClimate检查代码质量。您必须注册Codecov和CodeClimate(均支持GitHub登录)并在设置中启用包存储库。然后,将GitHubActions构建配置添加到.github/workflows/build.yml:#...jobs:build:runs-on:ubuntu-lateststrategy:matrix:python-version:[3.7,3.8,3.9]env:USING_COVERAGE:"3.9"步骤:-名称:Checkoutsourcesuses:actions/checkout@v2-name:SetupPythonuses:actions/setup-python@v2with:python-version:$-name:Installdependenciesrun:python-mpipinstall--upgradepippython-mpipinstallblackcoverageflake8flitmccabemypypylintpytesttoxtox-gh-actions-name:Runtoxrun:|python-mtox-name:UploadcoveragetoCodecovuses:codecov/codecov-action@v1if:contains(env.USING_COVERAGE,matrix.python-version)with:fail_ci_if_error:truebuild.yml和我们之前做的一样,GitHub测试有毒。tox-gh-actions包和USING_COVERAGE设置确保tox使用与strategy.matrix所需的GitHub操作相同的Python版本。最后一步将测试覆盖率发送给Codecov。CodeClimate不需要单独的步骤-它会自动发现存储库更改。现在,提交、推送并在一分钟内享受结果。让每个人也喜欢在README.md中添加徽章:[![PyPIVersion][pypi-image]][pypi-url][![BuildStatus][build-image]][build-url][![CodeCoverage][coverage-image]][coverage-url][![CodeQuality][quality-image]][quality-url]...[pypi-image]:https://img.shields.io/pypi/v/podsearch[pypi-url]:https://pypi.org/project/podsearch/[build-image]:https://github.com/nalgeon/podsearch-py/actions/workflows/build.yml/badge.svg[build-url]:https://github.com/nalgeon/podsearch-py/actions/workflows/build.yml[coverage-image]:https://codecov.io/gh/nalgeon/podsearch-py/branch/main/graph/badge.svg[coverage-url]:https://codecov.io/gh/nalgeon/podsearch-py[quality-image]:https://api.codeclimate.com/v1/badges/3130fa0ba3b7993fbf0a/maintainability[quality-url]:https://codeclimate.com/github/nalgeon/podsearch-py是不是很酷?D.任务自动化tox很好,但是开发起来不是很方便。运行单个命令(如pylint、coverage等)要快得多。但是它们非常冗长,所以我们将一些无意义的操作自动化。让我们为Makefile的频繁操作创建简短的别名:.DEFAULT_GOAL:=help.PHONY:coveragedepshelplintpushtestcoverage:##Runtestswithcoveragecoverageerasecoveragerun--include=podsearch/*-mpytest-racoveragereport-mdeps:##Installdependenciespipinstallblackcoverageflake8mccabemypypylintpytesttoxlint:##Lintandstatic-checkflake8podsearchpylintpodsearchmypypodsearchpush:##Pushcodewithtagsgitpush&&gitpush--tagstest:##Runtestspytest-raMakefile这是我们的任务:$makehelpUsage:make[task]taskhelp--------coverageRuntestswithcoveragedepsInstalldependencieslintLintandstatic-checkpushPushcodewithtagstestRuntestshelpShowhelpmessage为了让代码更简洁替换掉原来的make调用build.yml步骤:-name:Installdependenciesrun:|makedeps-name:Runtoxrun:|maketoxE。CloudpublishGitHub有能力为我们运行flitpublish。让我们创建一个单独的工作流程:name:publishon:release:types:[created]jobs:publish:runs-on:ubuntu-lateststeps:-name:Checkoutsourcesuses:actions/checkout@v2-name:SetupPythonuses:actions/setup-python@v2with:python-version:"3.9"-name:Installdependenciesrun:|makedeps-name:PublishtoPyPienv:FLIT_USERNAME:${{secrets.PYPI_USERNAME}}FLIT_PASSWORD:${{secrets.PYPI_PASSWORD}}run:|makepublishpublish.ymlPYPI_USERNAME和PYPI_PASSWORD在存储库设置中设置(设置>机密>新存储库机密)。使用您的PyPi用户名和密码,或者更好-API令牌。现在GitHub会在创建新版本后自动发布包。您的包裹已准备就绪!它拥有人们梦寐以求的一切:干净的代码、清晰的文档、测试和云构建。是时候告诉你的同事和朋友了。这些设置将使您的Python包很棒:pyproject.tomltox.iniMakefilebuild.ymlpublish.yml
