【CSDN 编者按】本文主要批评了 Python 语言在专业应用中的不足。作者通过多年的经验,指出 Python 在大型应用中的问题,如动态和鸭子类型导致的运行时错误、性能问题、内存管理困难等。尽管 Python 易于上手,但作者认为其不适合超过 100 行代码的项目,并推荐使用更严格、类型安全的编程语言,如 Rust 和 Go。
原文链接:https://josvisser.substack.com/p/why-python-is-terrible
未经允许,禁止转载!
上周,我无意中发现了一篇为初级开发人员提供了关于选择哪种编程语言以获取更佳工作机会建议的 LinkedIn 帖子。帖子中把 Python 排在了第一位,但我对此不敢苟同。
尽管我不愿意承认,但不得不同意帖子作者的一些观点:Python 的确很受欢迎,掌握它将有助于你找到工作。然而,Python 的持续受欢迎其实是一大问题,它的持续使用将让我们的行业倒退许多年。
基于多年大型 Python 应用程序的开发经验,我将对其做出非常尖锐的批评。
用 Python 开发大型应用,问题不断
使用 Python 构建大型应用就像用乐高积木建造核反应堆一样:色彩鲜艳、上手容易,但当反应堆运行了一段时间后,辐射泄漏无处不在,无人敢触碰,致使人们不断拼凑新积木以保持其运行——而正确的做法是:使用合适的建筑材料重新建造。
Python 的问题主要在于,它是一种具有动态和鸭子类型(duck typing)的解释型语言。我们无法预先知道一组语句是否总是工作,这取决于输入的数据。我们需要全面检查所有输入数据,但历史证明我们在这方面的表现不佳。更糟的是,Python 的鸭子类型会产生巧妙但可怕的代码,这总是令人陷入困境。
多年来,在开发大型 Python 应用程序的过程中,我看到并经历了一些可怕的事情,如果我们的应用程序是通过明智、编译、类型安全的语言编写的,这些事情就不会发生。
几年前,我成功说服了组织使用 Rust 重构系统,后来事实证明这是一个非常明智的决定。
我在生产环境中多次启动大型 Python 应用程序的新版本,却立即遇到了由异常引发的错误。这些异常明确指出代码永远无法工作,因为它从未被执行过:不在开发人员工作站上,不在单元测试中,也不在集成测试中。
关于 Python,一些拥护者主张,这些问题并非语言本身的缺陷,而是代码审查和测试策略的问题。然而,这种观点是错误的。仅仅理论上能够查看和测试每一行代码及所有可能的输入和场景,并不意味着这在实际操作中是可行的。优秀的编程语言可以让你不必审查和测试所有代码的情况下就可以避免很多错误。若要对每一个 "a = b + c" 进行彻底审查和测试,我的程序将永远无法上线。而对于使用 Python 编写的程序,这可能实际上是一件好事。
在审查 Python 函数时,我经常想知道是否有任何调用,以及使用了何种参数。由于没有能够提供全局视图的编译器和链接器,我通常不得不对代码库进行全文搜索,以寻找调用点。可惜的是,即使没有找到结果,删除函数后程序可能仍会崩溃。你永远无法确定程序是否会在某些特定条件下崩溃,所以最安全的做法就是保留该函数,这就导致了冗余代码的产生。
有些人可能会辩称,这是不良编程模式的问题。然而,他们再次误解了事实。优秀的编程语言应确保你不能编写结构上有缺陷的程序。在创建二进制文件之前确保所有必要的代码存在都是合理的,不是吗?再者,由于 Python 缺乏动态类型检查,以及在运行时判断事物是否合理的能力,常常引发了这些不良编程模式导致的重构问题。
Python 性能不佳,运行缓慢
Python 的性能也是一个问题。我的笔记本电脑有 10 个 CPU 核心,但 Python 应用程序仅能有效使用大约 1.2 个核心。这是怎么回事?幸运的是,我们还可以借助 1980 年代的技术来解决这个问题!我曾参与一个使用 Python 编写的服务项目,该服务通过 fork 工作进程来处理请求,确保所有核心都得到利用。
然而,这些工作进程很快耗尽了内存。为解决这一问题,我们让每个工作进程在处理了一定数量的请求后自行终止,以便让 Linux 为我们进行内存管理。虽然这本身不是 Python 的问题,但 Python 的运作方式使情况变得更糟。
fork 操作引发了一些副作用:Python 的引用计数机制阻碍了写时复制的效果,因为即使是只读变量的内存块也会被实际写入以执行引用计数操作,导致工作进程的物理内存占用剧增。我们解决了这个问题,方法是通过修改解释器,使其对主进程创建并由工作进程继承的所有变量使用一个特殊的引用计数值,并且不改变具有该特殊值的引用计数。虽然这个解决方案很巧妙,但其实是不必要的。如果要让解释器真正为你服务,必须进行修改,那解释型语言的简便性还有何价值?
Python 给我带来了无尽的困扰,它的运行速度缓慢,显然不适用于编写超过大约 100 行代码的程序。
为何很多人还愿意继续使用它?
我听到的主要理由是 Python “易于使用”。然而,这不仅不符合事实,而且是一种误导。它显示了人们对总体拥有成本(Total Cost of Ownership,TCO)工作方式的理解有误。对于任何真正用于生产的重要软件,80% 或更多的成本产生在初始开发之后。那是我们运行、调试、添加功能和重构的阶段。如果有80%的时间被消耗在调试和解决那些上世纪60年代的编译器就能发现的问题上,那么开发速度提高一倍的意义又在哪里?
你的编程语言易于使用固然值得称赞,但那并不是你的主要任务。你的工作是编写符合要求、可靠、易于维护和高效的软件,而用 Python 编写这样的代码异常困难。
问题:那么我们为什么还要使用它?答案:使用 Python 是一种错误的经济学选择,也就是说,它看起来可以节省一些成本,但实际上会造成更大的损失。
遗憾的是,写软件很难,但好的编程语言能够使编写合格的程序稍微容易一些,通常是以增加更多复杂性为代价。那个阶段的开发对整体并不重要,但因为它是第一个阶段,在人们的思考中占有重要地位,对我们项目规划中的缺陷产生了深远影响。
使用 Python,你可以迅速编写并执行代码,就如同你在建造摩天大楼时仅搭建几堵预制墙一样,未考虑地基的牢固性。然而,我们构建软件的方式不应该像搭建摩天大楼那样仓促行事。
有人声称 “Python 非常适合作为其他库的粘合代码”,但这并不完全准确。实际上,除了 Python 被广泛使用和接受外,它的适用性并没有特别突出。这与 QWERTY 键盘并不是最优设计,却因为大众习惯而被广泛接受的情况相似。
我已转向 Go 语言
相较之下,我已将所有业余编程转向 Go 语言。Go 在易于编写和类型安全性方面与 Python 几乎持平,构建迅速,并能生成优化良好的本地代码二进制文件。虽然 Go 也有缺点,但在编写可靠、快速的代码方面,它比 Python 更有优势。
确实,如果你擅长编写 Python 但不熟练使用 Go 或其他高效的编程语言,你可能需要重新审视自己的软件开发能力。虽然这听起来严厉,但作为专业软件开发人员,你应具备使用专业工具的能力。
最后,虽然 Python 在许多方面并不出色,但它的确有一个值得称赞的特点:它是由一位荷兰人发明的!
广大网友激烈讨论
这篇文章引起了广大网友的激烈讨论,有些人力挺 Python,而有些人则持有相反观点,也有些网友持中立态度。
支持的一方:有些人认为 Python 是一种灵活、易用、富有表达力的语言,适合用于数据科学、机器学习、Web 开发等领域,拥有丰富的库和社区支持。有网友强调 Python 在教育和初学者入门方面的优势。它的语法简单,易于学习,在教学和快速原型开发方面有独特的优势。
反对的一方:认为 Python 是一种缺乏类型安全、错误处理混乱、难以重构的语言,不适合用于复杂、大规模、高可靠性的软件工程项目,应该被其他更现代、更专业的语言取代。有网友认为 Python 的性能较差,特别是与 C、C++ 等编译语言相比。这可能会限制其在某些高性能计算场景中的应用。有网友提到 Python 的一些库和工具可能存在问题,例如包管理工具的复杂性和一些库的不稳定性。
中立的一方:有些人认为 Python 是一种有优点也有缺点的语言,取决于使用场景和个人喜好,没有绝对的好坏,应该根据实际需求选择合适的工具。
参考链接
动态:https://en.wikipedia.org/wiki/Type_system#Dynamic_type_checking_and_runtime_type_information
鸭子类型:https://en.wikipedia.org/wiki/Duck_typing
冗余代码:https://en.wikipedia.org/wiki/Cruft
动态类型检查:https://en.wikipedia.org/wiki/Type_system#Dynamic_type_checking_and_runtime_type_information
Python 的运作方式使情况变得更糟:https://www.pythontutorial.net/advanced-python/python-garbage-collection/
写时复制:https://en.wikipedia.org/wiki/Copy-on-write
写软件很难:https://medium.com/@josvisser/why-programming-is-hard-90cb7ff06dcf
QWERTY 键盘:https://smallbusiness.chron.com/advantages-disadvantages-using-qwerty-keyboard-66874.html
荷兰人:https://en.wikipedia.org/wiki/Guido_van_Rossum
粉丝福利: