当前位置: 首页 > 科技观察

收集!四款Python项目管理和构建工具

时间:2023-03-17 17:50:23 科技观察

Python已经很久没有一个事实上的标准项目管理和构建工具,以至于Python项目的结构和构建方式五花八门。这或许反映了Python的自由意志。不像Java经历了最初的手工构建,到半自动化的Ant,再到Maven,基本上已经是事实标准了。期间,Maven也接受了Gradle(Android项目主推)、SBT(主要是Scala项目)、Ant+Ivy、Buildr等其他挑战,但很难撼动Maven的江湖地位,其他几乎遵循Maven的目录布局。回到Python,pip、pipenv、conda等包管理工具已经产生,但是对于项目的目录布局一直没有达成一致。构建方面,延续了传统的Makefile方式,增加了setup.py和build.py,使用程序代码安装构建。关于项目目录布局,有项目模板,然后做成工具应用项目模板。下面简单浏览一下四个工具的使用CookieCutterPyScaffoldPyBuilderPoetryCookieCutter一个经典的Python项目目录结构generateAPythonproject...project_name[PythonBoilerplate]:sample...cookiecutter生成的最终项目模板如下所示:$treesamplesample├──AUTHORS.rst├──CONTRIBUTING.rst├──HISTORY.rst├──许可证├──MANIFEST.in├──Makefile├──README.rst├──docs│├──Makefile│├──authors.rst│├──conf.py│├──contributing.rst│├──history.rst│├──index.rst│├──installation.rst│├──make.bat│├──readme.rst│└──usage.rst├──requirements_dev。txt├──sample│├──__init__.py│├──cli.py│└──sample.py├──setup.cfg├──setup.py├──tests│├──__init__.py│└──test_sample.py└──tox.ini3directories,26files这大概就是现在流行的目录结构的主要框架了。主要元素有:$treesamplesample├──Makefile├──README.rst├──docs│└───index.rst├──requirements.txt├──sample│├──__init__.py│└──sample.py├──setup.cfg├──setup.py└──tests├──__init__.py└──test_sample.py项目示例目录重复将Python源文件放在sample目录下,测试文件放在tests目录下,添加文档的docs目录,README.rst,其他setup,setup.cfg和Makefile文件进行构建。这其实是一个非常经典的Python工程结构,接下来的build会用到make命令,输入make就会看到Makefile中定义的指令。$makecleanremoveallbuild,test,coverageandPythonartifactsclean-buildremovebuildartifactsclean-pycremovePythonfileartifactsclean-testremovetestandcoverageartifactslintcheckstyletestruntestsquicklywiththedefaultPythontest-allruntestsoneveryPythonversionwithtoxcoveragecheckcodecoveragequicklywiththedefaultPythondocsgenerateSphinxHTMLdocumentation,includingAPIdocsservedocscompilethedocswatchingforchangesreleasepackageanduploadareleasedistbuildssourceandwheelpackageinstallinstallthepackagetotheactivePython'ssite-packages为使用上面的构建过程,需要安装相应的包,如tox,wheel,coverage,sphinx,flake8,它们都可以通过pip来安装。之后可以maketest,makecoverage,makedocs,makedist等,其中makedocs可以生成非常漂亮的Web文档。PyScaffold创建项目PyScaffold顾名思义,是一个创建Python项目脚手架的工具,安装使用:$pipinstallpyscaffold$putupsample这样创建一个Python项目,目录结构类似于上面cookiecutter选择的模板,只不过它把源文件放在了src目录下,而不是sample目录下。$treesamplesample├──AUTHORS.rst├──CHANGELOG.rst├──CONTRIBUTING.rst├──LICENSE.txt├──README.rst├──docs│├──Makefile│├──_static│├──authors.rst│├──changelog.rst│├──conf.py│├──contributing.rst│├──index.rst│├──license.rst│├──readme.rst│└──requirements.txt├──pyproject.toml├──setup.cfg├──setup.py├──src│└──sample│├──__init__.py│└──skeleton.py├──tests│├──conftest.py│└──test_skeleton.py└──tox.initox工具用于构建整个项目。tox是一种自动化测试和构建工具,可在构建过程中创建Python虚拟环境,从而为测试和构建提供一个干净的环境。tox-av可以显示tox.ini中定义的所有任务:$tox-avdefaultenvironments:default->Invokepytesttorunautomatedtestsadditionalenvironments:build->BuildthepackageinisolationaccordingtoPEP517,见https://github.com/pypa/buildclean->Removeolddistributionfilesandtemporarybuildartifacts(./build/dist)docs->Invokesphinx-buildtobuildthedocsdoctests->Invokesphinx-buildtorundoctestslinkcheck->Checkforbrokenlinksinthedocumentationpublish->Publishthepackageyouhavebeendevelopingtoapackageindexserver.Bydefault,itusestestpypi.IfyoureallywanttopublishyourpackagetobepubliclyaccessibleinPyPI,usethe`----repositorypypi`option.要执行哪个命令便用tox-ebuild,tox-edocs,等等,下面是PyScaffold的使用动画:https://yanbin.blog/wp-content/uploads/2021/09/pyscaffold-demo.gif在我体验tox命令的过程中,每一步似乎都比较慢,创建虚拟机应该需要一些时间。PyBuilder最好看看另一个构建工具PyBuilder,它创建的目录结构和Maven很接近,一起来看看吧。$pipinstallpybuilder$mkdirsample&&cdsample#需要手动创建工程目录$pyb--start-project#回答一些问题后,创建需要的目录和文件,然后看它的目录结构:$treesample.├──build.py├──docs├──pyproject.toml├──setup.py└──src├──main│├──python│└──scripts└──unittest└──python构建过程仍然使用pyb命令,你可以使用pyb-h查看帮助,pyb-t列出所有任务,PyBuilder任务以插件的形式添加,插件在build.py文件中配置。$pyb-tsampleTasksfoundforproject"sample":analyze-Executeanalysisplugins.dependsontasks:preparerun_unit_testsclean-Cleansthegeneratedoutput.compile_sources-Compilessourcefilesthatneedcompilation.dependsontasks:preparecoverage-dependsontasks:verifyinstall-Installsthepublishedproject.dependsontasks:packagepublish(optional)package-Packagestheapplication.Packageapythonapplication.dependsontasks:compile_sourcesrun_unit_tests(optional)prepare-Preparestheprojectforbuilding.CreatestargetVEnvsprint_module_path-Printthemodulepath.print_scripts_path-Printthescriptpath.publish-Publishestheproject.dependsontasks:packageverify(optional)coverage(optional)run_integration_tests-Runsintegrationtestsonthepackagedapplication.dependsontasks:packagerun_unit_tests-Runsallunittests.RunsunittestsbasedonPython'sunittestmoduledependsontasks:compile_sourcesupload-UploadaprojecttoPyPi.verify-Verifiestheprojectandpossiblyintegrationtests.dependsontasks:run_integration_tests(optional)$pybrun_unit_testssamplePyBuilder还在构建或测试之前创建一个虚拟环境。从0.12.9版本开始,可以通过参数--no-venvs跳过创建虚拟环境的步骤。使用--no-venvs的Python代码将在当前运行pyb的Python环境中执行,需要手动安装所需的依赖项。该项目的依赖项也在build.py文件中定义。@initdefset_properties(project):project.depends_on('boto3','>=1.18.52')project.build_depends_on('mock')然后在执行pyb创建虚拟环境的时候会安装上面的依赖,在里面运行测试它与构建。Poetry最后的Poetry,感觉这是一个更成熟也更活跃的Python构建。它具有更强大的信任管理功能。您可以使用poetryaddboto3添加依赖项,poetryshow--tree显示依赖树。查看如何安装和创建项目。$pipinstallpoetry$poetrynewsample它创建的项目比上面简单:──test_sample.py如果给poetrynew加上--src参数,那么源文件目录sample会放在src目录下,即sample/src/sample。poetryinit会在当前目录生成一个pyproject.toml文件,目录的生成等需要手动完成。它不关注文档生成、代码规范检查或代码覆盖率。它的项目配置比较集中,都在pyproject.toml文件里,什么是toml?它是一种配置文件格式Tom'sObvious,MinimalLanguage(https://github.com/toml-lang/toml)。pyproject.toml有点类似于NodeJS的package.json文件,比如poetryadd的行,poetryinstall命令。#将boto3的依赖添加到pyproject.toml中并安装(add也可以从本地或git安装依赖),poetryaddboto3#会根据pyproject.toml文件中的定义安装对应的依赖到当前Python虚拟环境#比如在/lib/python3.9/site-packages目录下,模块安装完成后,测试用例也可以使用poetryinstall其他主要:1.poetrybuild#Buildinstallable*.whlandtar.gz文件2.poetryshell#虚拟环境会根据pyproject.toml文件中定义的依赖来创建和使用3.poetryrunpytest#使用pytest运行测试用例,例如tests/test_sample.py4.poetryrunpython-munittesttests/sample_tests。py#运行unittest测试用例5.poetryexport--without-hashes--outputrequirements.txt#导出requirements.txt文件,--dev导出包含dev的依赖,或者使用poetryexport--without-hashes>requirements.txtpoetry运行即可执行任何系统命令,但是它将在它想要的虚拟环境中执行。所以可以想象,poetry项目必须使用poetryrun...命令来支持sphinx、coverage或者flake8才能生成文档或者coverage。在示例目录(与pyproject.toml文件同级)中创建文件my_module.py,内容为:defmain():print('hellopoetry')并在pyproject.toml中写入[tool.poetry.scripts]my-script="sample.my_module:main"然后执行$poetryrunmy-script会输出"hellopoetry"。通过对以上四个工具的了解,从cookiecutter-pyproject->PyScaffold->PyBuilder->Poetry依次降低了项目结构的复杂度,使用难度大致相同。