9步获得更专业的Python代码


原作者: Vladimir I. Iglovikov,翻译已获得原作者授权, 原文链接

Vladimir I. Iglovikov, Lyft 的计算机视觉工程师,主要研究自动驾驶。曾服役于俄罗斯空降部队。UC Davis 获得过理论凝聚态物理学博士的学位。Kaggler(Grandmaster),曾获得过 Carvana 图像遮蔽挑战的冠军,以及 Dstl 卫星图像特征检测挑战的第三名。
我会定期浏览学术论文,发布的数据集或Kaggle竞赛解决方案的补充代码。

我非常感谢分享了代码以复现其结果的研究人员,以及那些参加机器学习竞赛并分享解决方案的人。这些代码聊胜于无,但是我相信仍可以提高代码可读性。

看到的这些代码让我想起我还在学术界时写的代码。我其实并不喜欢,所以我进入了工业界。在现代世界中能够写代码已经与了解英语一样重要。其实成为一个优秀的程序员的最好的方式是加入一家具有高代码标准的公司。尽管如此,在这里我还是介绍一下独自一人编程的情况。

本文的目标读者是研究人员,数据科学家和初级软件开发人员。成为更好的程序员是一个水到渠成的过程。你写的代码越多,你的收获自然也会越多。

通过简单地微调开发过程也会让你的代码看起来更棒。这些微调实施起来很简单,每一步不会超过5分钟。每一处改变都会让你做的更好。

我们都很懒,如果有些事情属于“如果你能做就好了”,我们能找到很多“正当理由”来搁置。有时候我们不得不强迫自己才能真的做好。因此一开始我们要让自己别无选择而这样做,之后就会慢慢习惯。

另一个原因是做决策会消耗意志力,如果每一个小决定我们都深思熟虑,这一定会让我们精疲力尽。当我们不给自己留选择的时候,我们才能保存宝贵的心力。有兴趣的同学可以参考这本书: “Willpower: Rediscovering the Greatest Human Strength” 书里全面系统的讨论了这个主题。

I: 利用版本控制来跟踪代码中的改动

版本控制看起来人尽皆知,但其实不然。在研究生院里,我的导师是一个大牛,他开发了一种算法来执行Hubbard模型的量子蒙特卡罗模拟。代码被全世界许多研究员用来推进凝聚态物理的理论研究。当我开始这个项目的时候,我发现竟然没有一个集中的代码仓库。代码的交换都是通过邮件进行的。一位科学家开发的debugger和新功能都无法共享给其他用户。此外,我发现我的同事竟然就是用不同的文件夹来做版本控制。

版本控制和Github或其他服务器上的集中的代码仓库是必要的。许多研究人员确实正在这么做。但是如果你看看CS以外的学科,大部分教授和研究生仍处于使用文件夹进行版本控制和通过电子邮件收发代码的阶段。

Q: 什么时候开始在项目中使用git?

A: 从代码的第一行开始。

Q: 什么时候需要在Github上面创建仓库并将代码推送上去?

A: 从代码的第一行开始。如果你认为由于法律或其他原因不能共享你的代码,那就创建一个私有仓库。在其他情况下,直接创建公开仓库。

当人们等到代码看起来不错再公开是不对的。我的很多同事都感觉在GitHub里面存放不完善的代码很不安全。他们担心受到他人的负面评价。实际上,甚至没有人会评判你。另外,你现在写的每一行代码在6个月之后重新来看都会感觉很糟糕。

私有仓库比没有仓库好,公共仓库比私有仓库好。

我也喜欢Kaggler在比赛结束后公开他们的pipelines。这是一个好的习惯并且对他们以及所在社区都有帮助

此外,还有一个叫Sourcegraph的工具,可让你在所有公共Github仓库中执行搜索。非常方便,可以让你工作效率更高。

Links:

II: 不要推送到主分支

在团队工作时,你不会直接推送到主分支。你创建一个单独的分支,编写代码,创建一个拉取请求(Pull Request),合并拉取请求到主分支。这比直接推送复杂的多:为了合并拉取请求,你的更改要通过各种检查。手动检查包括你的协作者进行代码复查。自动检查包括了语法,样式,测试等等。

当你独自工作的时候,你不必进行繁琐的代码复查,但是自动检查的功能仍然存在。

至关重要的是在GitHub上调整设置,以便即使你想推送到主分支也办不到。像我们前面讨论的,这会防止出差错并节省我们的意志力

III: 使用持续集成(CI)或者持续交付(CD)系统

完成创建分支并合并是刚需。主要原因是他要对代码改动进行检查。当你设置好了持续集成系统后,你创建的所有拉取请求都会被检查,并且只有在所有检查通过后再合并请求

有很多提供 CI / CD功能的服务。比如GitHub Actions, CircleCi, Travis, Buildkite 等。

我个人推荐GitHub Actions。因为他是免费的,可同时在私有仓库和公共仓库上使用,易于上手。

所有这些听起来都很复杂,但是实际上,你只需要在仓库中添加一些配置文件即可。

  • 简单的例子:一个带有帮助功能的库,我会检查代码样式,格式,并运行测试。
  • 复杂的例子:在Albumentations库中,针对不同的Python版本和操作系统(Linux,Windows,MacOS),我都会检查语法,代码样式,运行测试,检查自动文档的构建。

划重点!!GitHub仓库设置也要更改。例如,如果没有通过所有检查,你就无法合并请求。

Links:

IV: 代码格式化

格式化同一段代码的方法有很多。

  • 定义函数之间要有多少空行?
  • 一行代码最长可以是多长?
  • 导入包(import)的先后顺序如何?
  • 应该使用哪种引号来定义字符串?

有一些工具可以做代码格式化。它们可以修改代码以符合各种格式要求。

通用型格式化程序:

  • YAPF:非常灵活,你可以配置它以适合需要的样式。
  • Black:不灵活,只能修改一行代码的最长长度。

选择一个然后加到你的CI / CD配置中,我喜欢Black。他让我的所有项目没有太大的变化。

代码格式化减少了上下文切换,可以增加代码可读性。

还有更多的个性化格式,比如isort,他只会对导入的包进行排序。

你只需要在两个地方格式化你的代码:

  1. 在CI / CD中,在这里,你以检查的方式运行他,你会知道什么代码需要被格式化,但是源代码仍然保持不变。
  2. 提交(commit)更改之前在本地运行,你的代码才会被重新格式化。

Links:

V: Pre-commit hook

在上一步中,我们讨论了在提交之前在本地按标准格式化代码的重要性。

假设用black和isort,我们需要运行:

black .
isort

看起来还是有点麻烦的。一个更好的解决方案是创造一个bash脚本来运行(例如“ code_formatter.sh”)。创建这样的脚本是挺受欢迎的,但是还是不得不强迫自己多增加这样一个流程大家才会使用。

另一个更好的办法是pre-commit hook。跟bash脚本类似,但你每次commit之前运行的内容都会自动执行。

git commit -m “<commit message>

这看起来似乎差异不大,但事实并非如此。 使用pre-commit,可以少让我们做选择,并且根据前文讨论的,这样的效果一般更好。

Q:PyCharm有很好的代码格式化工具。为什么我还需要一个pre-commit hook?

A:你可能忘记使用PyCharm格式化代码。 此外,当两个或更多人工作时,我们也要确保他们的格式相同。 对于pre-commit hook,所有人将拥有与同样的仓库配置。 我建议同时使用这两个方法,即预先提交一个pre-commit hook,并使用PyCharm格式化代码。

Q:如果我不从控制台执行commit而是直接从PyCharm里commit怎么办?

A:你可以将PyCharm配置为在每次提交时运行pre-commit hook。

Links:

Pre-commit hook

VI: Linters

Linters不会更改代码,而是会对其进行检查并查找可能存在的问题。

最常见的是flake8,它可以找到:

  • PEP8错误和警告。
  • 一致的命名规范。
  • 函数的循环复杂度。
  • 以及其他带有一组插件的东西。

这是一个功能强大的工具,强烈建议将其添加到CI / CD配置以及pre-commit hook中。

Links:

VII: Mypy: 静态类型检查器

从python3开始,你可以在定义的函数里添加类型注释。 虽然是可选的但强烈建议。

原因之一是这样的带有类型注释的代码会容易的多。

当你在代码中看到:

x: pd.DataFrame

它会比下面这个更易理解

x

当然,首先我们不应该将变量命名为“x”。尽管如此,在这里我仍想讨论简单,自动化的方法来改进代码,而好的命名是要比简单的更难。

类型注释是可选的,没有他们代码仍然可以运行。这里有一个工具叫Mypy的工具可以检查:

  • 函数和输入参数的类型检查
  • 变量类型和运算之间的一致性

这是一个强大的工具。所有大型科技公司都用他来检查python代码的每个拉取请求。

它迫使你写易于阅读,重写过于复杂,写的不好的函数,并且帮你找到bugs.

Mypy检查应该添加到CI / CD和pre-commit hook.

Links:

VIII: 更多 Pre-commit hook 检查

您可以使用许多不同的东西扩展 pre-commit hook.

  • 删除行末空格。
  • 代码的末尾是新的一行。
  • 排序运行依赖包。
  • 检查yaml文件的格式正确。

您可以为代码格式化创建自己的hook,并检查应该自动化的hook。

Link:

IX: 外部工具

利用机器学习来分析拉取请求上的代码是一个有前景的新方向。

已经开发出来的一些工具对公共仓库是免费的,其中一些对私有存储库是免费的。为什么不在你的公共代码上启用它们呢:)

Links:

结语

如果一个人至少实现了其中一些技巧,则他的代码将变得更容易阅读。

但这只是第一步。

还有其他标准技术,例如:

  • Unit tests
  • Unit tests with Hypothesis
  • Python environments
  • Building packages
  • Dockerization
  • Automatic documentation

但是,它们执行起来就不像上述的步骤那么容易。 因此,我们可以下次再讲他们:)

P.S. 对于那些在实现我所描述的技术时遇到问题的读者,请直接联系我,我可以详细讲述相应的要点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值