3

每次修 Python 代码的 bug 的时候总会想念 Rust

 3 years ago
source link: https://blog.lilydjwg.me/2018/9/28/miss-rust-while-fixing-python-code.213564.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

每次修 Python 代码的 bug 的时候总会想念 Rust

本文来自依云's Blog,转载请注明。

俗话说:由俭入奢易,由奢入俭难。

之前写 Python,老是在实现完一个特性之后,弄出来几个 AttributeError: 'NoneType' object has no attribute 或者 TypeError: list indices must be integers or slices, not str,还有 TypeError: can only concatenate str (not "int") to str 这样的错误。一看就明白自己又是哪里一不小心疏忽了,稍微修一下就好。

后来啊,我遇见了 Rust,整个流程就变了。之前写的时候,基本上都是通过手动测试来发现这种问题。为了高效、不破坏性地测试,需要控制测试的数据量,需要保证出错的时候相关的数据不会处于某种中间状态。当然在服务器上跑的脚本,我还要来来回回地传更新的脚本,或者弄个本地测试环境。而这一切,可能不过是为了跑一个成功之后再也不会用到的小程序,比如之前分析抓包数据的那次。而在 Rust 里,这些最容易犯的错误,cargo check 一下,编译器基本上能全给你指出来。所以有时候写一些小工具我也用 Rust,虽然写起来慢,但写好就能正常运行,不用反复试错,多好啊!

最近给 Arch Linux 中文社区的自动打包机器人 lilac 增加新特性。结果实现完部署之后,夜里就被 lilac 叫起来修 bug 了,还一下子就是仨……(lilac 很难本地测试,而短暂地服务中断又没多大影响,所以我都是不进行本地测试的。)

第一个 bug 是,与 dict.get 不一样,getattr 是没有默认值的。Python 里这种不一致很多,比如 configparser 里默认值要用关键字参数指定。Rust 遇到类似的情况,就会返回一个 Option。或者如果 API 决定如果不存在就 panic 的话,那么它就会直接返回我要取的值的类型,而不会包一层 Option。而我后边的代码是预期到这里可能取不到那个属性的,所以弄错了就会类型不匹配。

第二个 bug 是局部变量在一个分支上没有初始化。Rust 当然不会允许这种情况了。实际上 C 都不用担心这种问题,编译器会给出警告的,还有一些 linter 可以用。而 Python,很遗憾的是,我所使用的 pyflakes 并没有对此发出警告。我当然知道 pylint 那些。我很讨厌 pylint 和 jslint 这种不区分潜在 bug 和风格问题的 linter。我只需要工具在我可能疏忽的时候提醒我,而不需要它对我的编码风格指指点点,特别是那些指指点点往往是不对的。比如我的文件描述符变量名不叫 fd 难道要叫 fildes?

第三个 bug 是一个可能为 None 的变量我忘了先作 is not None 判断。这段代码如果初写的话我肯定是会注意到的,但是改的时候,只想着如果 pkg 里有冒号我得处理一下,就忘记了根本没有关联的包名的情况。Python 的 None,以及 C 和 C++ 的 NULL、Java 的 null、Lua 和 Ruby 的 nil、JavaScript 的 undefined 和 null,被称作是十亿美元错误,给无数程序员和用户带来了无尽的 bug。幸好这个东西在 Rust 里不存在:表达「没有值」的值没有被作为特殊值存在于几乎所有类型中,而是作为一类类型的可能的值之一。想要使用「正常」的值,就需要显式地进行类型转换,所以不可能被不小心忽略掉。顺便说一下,Go 里也有 nil 这种东西,以至于会出现这种不容易发现的 bug

Python 现在也给出了解决方案:类型注解,提供类似的类型检查。不过检查器是第三方的,也并不十分完善。等我找到机会试用过之后再来写感想啦。

发送到 Kindle


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK