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

Python工具链让你写的代码更规范

时间:2023-03-12 10:06:34 科技观察

本文转载自微信公众号《Python中文社区》,作者100gle。转载本文请联系Python中文社区公众号。从以前不会敲Python代码的新手,到现在敲Python代码的老鸟,除了通过大量的学习和实践,让我写出Pythonic代码变得更简单之外,大部分的那时我仍然感谢许多有用的工具来协助我,检查我代码中的问题并帮助我编写更规范的代码。学习和实践新知识对大多数人来说可能没有统一的公式,但是使用工具至少可以让我们大家有统一的风格,更容易与他人协作。因此,无论是初学者还是成长中的新人,使用能够帮助自己编写更规范代码的工具都是非常有必要的。black随着PEP8规范的提出,Python社区也有了自己的一套Python代码规范指南。但是我相信大多数人并不会真正去浏览或者写下规范中的大部分内容,因为这些内容往往过于琐碎,以至于我们在实际开发中写代码的时候很难写代码。检查我们是否符合PEP8标准。所以最好的办法就是借助格式化工具来帮助我们完成这种机械的操作。早期Python比较知名的格式化工具有autopep8和谷歌的yapf,但在实际过程中或多或少需要进行一些配置。如果你用过Go语言,你可能会对Go自带的gofmt感到惊奇。因为它既不会要求你做多余的配置,又会在每次保存代码的时候强制你格式化,所以不管你协作的同事的代码风格和个人习惯如何,它都可以转换成符合工程的,规范样式。而black就是像gofmt这样所谓的“不妥协”(uncompromising)的Python格式化工具,它可以让我们把更多的时间和精力花在编写代码上,而不必过多关注格式化配置细节。因此,只要我们在团队协作中使用黑色工具,大多数情况下代码看起来是非常统一的。例如下面一段代码(来自官方的例子):defvery_important_function(template:str,*variables,file:os.PathLike,engine:str,header:bool=True,debug:bool=False):"""Applys`variables`tothe`template`andwritesto`file`."""withopen(file,'w')asf:...因为very_important_function已经添加了类型注解,它是基于一些现有参数的宽度。它扩大了一点,所以如果我们显示的宽度不够,我们需要水平拖动才能查看参数信息;最好的方法是垂直排列,这样我们可以从上到下看到它。所以在使用black之后,上面的代码会是这样的:defvery_important_function(template:str,*variables,file:os.PathLike,engine:str,header:bool=True,debug:bool=False,):"""Applies`variables`tothe`template`andwritesto`file`."""withopen(file,"w")asf:...可以看出格式化函数的参数对齐清晰,可读性大大增强;而如果需要在函数中注释或添加参数,直接添加或删除一行即可,根本不需要调整其他参数的位置。black虽然还是一个实验项目,但是已经在一些主流的Python开源项目中被频繁使用,比如Pandas、SQLAlchemy、Pytest等,所以我们在实际开发中也可以放心使用。black的使用方法很简单,通过pipinstallblack安装到你的Python环境中,然后在代码中运行:black<项目文件夹/源文件夹/.py文件等>black命令行也提供了一些参数items(但不要太多),大多数时候,即使我们使用默认的也足够了,具体可以参考black的官方文档。isortisort是一个名为PyCQA(PythonCodeQualityAuthority)的组织维护的代码质量工具中的开源项目之一,也用于格式化代码。但与黑色不同的是,它主要是用来格式化我们导入的库或者模块。Python社区的生态一直很丰富,所以我们在开发项目的过程中经常会使用多个库或者同一个库中的多个模块,但是在没有规范的情况下,导入的部分可能会杂乱无章,散乱无序代码,所以我们在复现代码的时候,很可能会因为忘记导入一些模块而报错。就像官方的示例代码:frommy_libimportObjectimportosfrommy_libimportObject3frommy_libimportObject2importsysfromthird_partyimportlib15,lib1,lib2,lib3,lib4,lib5,lib6,lib7,lib8,lib9,lib10,lib11,lib12,lib13,lib14importsyslibfrom__future__importabsolute_importfromthird_party"print"("party"3print)有多个样式比如上面代码中,同一模块下的导入部分各占一行,同一模块下的导入部分只占一行等;并且还有重复进口的情况。因此,我们要么简单地将每个导入放在一行中,要么将来自同一模块的导入连接起来。默认情况下,isort将是后者:from__future__importabsolute_importimportosimportsysfromthird_partyimport(lib1,lib2,lib3,lib4,lib5,lib6,lib7,lib8,lib9,lib10,lib11,lib12,lib13,lib14,lib15)frommy_libimportObject,Object2,Object3print("Hey")print("yo")使用isort后,它会把我们每个.py文件的import部分的代码组织起来,按照内置库(和字母顺序)、第三方库和本地自拥有的模块。订单安排我们进口的零件。这样一来,我们的代码不仅看起来简洁多了,而且可以准确定位到我们导入了哪些部分。isort不会像black那样“固执”,也尽可能为你保留了一些可定制的配置项,以满足不同风格或团队规格的需求。但是它的使用却和黑色一样简单,你只需要在我们的环境中安装它,直接调用它:isort<项目文件夹/源文件夹/.py文件等>静态检查工具,比如Python,JavaScript这些动态类型的解释型语言没有Java、Go等静态类型编译语言编译时的检查机制。因此,当项目中代码过多时,会造成“动态一时的快感,重构火化”领域”的情况。虽然Python社区推动了PEP484提案,让Python具备了类型注解的能力,但不正确的使用是仍然难以达到静态语言编译检查的效果。因此,一些静态类型检查工具应运而生,以便于我们及时发现自己代码中的问题。目前Python的静态检查工具很多,比较有名的有几个:pylint:由PyQCA团队维护,可靠性高。配置项(这当然也是缺点),如果你在VSCode中写过Python代码,那么你可能会遇到让你安装pylint的情况;flake8:仍然由PyQCA团队维护,在功能上和pylint存在重叠,但也集成了PEP8、McCabe和第三方插件等多个部分,相对于pylint功能更丰富;可以说没有人比他更懂Python了,也算是比较权威的静态检查工具;pyright由微软开源,基于TypeScript和JavaScript编写,高度集成在VSCode中。对于经常使用VSCode写代码的人来说可能是更好的选择;pytype是开源的,由谷歌维护,但是相对于其他工具,检查会比较宽松。以上是使用人数较多,质量比较高的静态检查工具,可以根据自己或者团队的实际需求来选择;但是flake8和mypy在常规项目中通常被视为标准配置,这里我仅以flake8为例。和前面两个工具一样,先使用pipinstallflake8命令安装,然后使用:flake8<项目文件夹/源文件夹/.py文件等>大多数情况下,flake8会按照一些默认的规范检查代码,默认是根据pyflake的错误(或违例)码表进行检查,完整的码表可以在flake8官方?章节浏览;当然,我们也可以通过具体的命令行参数指定要检查的项目或者忽略一些东西:这里的flake8--selectE121example.py只会选择检查E121,它来自于pycodestyle码表中的一个项目。如果代码导入的模块或包没有缩进或挂起,那么flake8会在检查代码后抛出一条信息:example.py:5:9:E121continuationlineunder-indentedforhangingindent这对应于中第5行到第9行的代码example.py文件,我们可以直接根据flake8部分的结果修改检测失败的部分。工具链集成了上述工具,大多数情况下,可以通过IDE、脚本、GitHook等方式进行有效集成。通常,我在提交代码前预先使用isort、black、静态检查flake8仓库。由于black的特殊情况,经过isort等格式化工具处理后的代码会再次被格式化成black,所以black也提供了与其他工具兼容的配置项的通用选项,最大程度的与其他工具共存。根据black官方的建议,通常我们可以放在一些配置文件中,比如pyproject.toml、setup.cfg等,内容如下:multi_line_output=3include_trailing_comma=Trueforce_grid_wrap=0use_parentheses=Trueensure_newline_before_comments=Trueline_length=88一样对于flake8是这样:max-line-length=88extend-ignore=E203,W503所以我们可以把上面的内容写在一个配置文件里,这里我选择setup.cfg文件:[isort]multi_line_output=3include_trailing_comma=Trueforce_grid_wrap=0use_parentheses=trueensure_newline_before_comments=Trueline_length=88[flake8]max-line-length=88extend-ignore=E203,W503这样black、isort和flake8可以更好的协同工作;同时,我们可以把它放在一个脚本文件中,方便每次二次运行调用,大致类似:#code_fmt.shWORKDIR=$PWDisort$WORKDIR\&&black$WORKDIR--skip-string-normalization\&&flake8$WORKDIR当然我们也可以将其集成到我们的IDE中,比如在VSCode中,当我们安装好以上工具后,我们可以在设置项中关于Python的配置项中找到关于以上工具的配置栏。这里我以black为例:isort和flake8的设置类似。然后再次在设置中找到编辑器设置,勾选FormatonSave选项,这样每次我们保存代码文件的时候,它都会自动帮我们格式化:原文链接:https://mp.weixin。qq.com/s/yZVNpaqCFZDD4Z8wbON6Ww