【译文】Python–一种深受喜爱但永远存在缺陷的语言
Python 这门语言已经渗透到科技行业的各个角落,它的简洁性和易用性常常受到称赞。人工智能和数据科学等领域似乎都离不开它。
然而,当我们褪去便捷的外衣时,留给我们的却是一门挑战重重的语言,尤其是在长期开发和大型项目中。
写这篇文章的原因是什么?我一直在使用严格的语言,现在我加入了一个由 Python 开发团队牵头的项目。Python 与更严格的、以 JVM 为核心的语言 Go 或 C# 在开发流程上的差异可能会让人大吃一惊。请注意本文的偏见!
提要:随着项目规模的扩大,Python 最初的魅力往往会让人感到沮丧。它的简单性可能会导致复杂问题的出现,这使它成为长期开发的一个值得商榷的选择。
动态类型 = 无声错误的来源
Python 的动态类型是福也是祸。一方面,它允许灵活和快速的开发。另一方面,它可能导致难以察觉的细微错误。想象一下,在一个大型项目中,一个未键入的变量会在代码库中传播,导致一系列错误的连锁反应。
这些错误一直处于休眠状态,直到它们在运行时突然爆发,让开发人员束手无策。缺乏强制类型安全意味着 Python 在发现这些问题时为时已晚。虽然动态类型可以提高工作效率,但它也要求我们保持警惕并进行全面测试。
虽然动态类型赋予了灵活性,但也隐藏着潜在的危险。请看下面这个例子:
def calculate_total(items):
total = 0
for item in items:
total += item
return total
# Usage
shopping_cart = [10, 20, "30", 40]
print(calculate_total(shopping_cart)) # Oops! Concatenation instead of addition
在这种情况下,动态类型允许字符串 “30 “悄悄地溜进我们的数字计算中,导致了意想不到的行为。
简单?
Python 的简单语法经常被称赞为其标志。它鼓励可读性和简洁性,使其成为初学者的绝佳选择。然而,这种简单也可能具有欺骗性。
新手开发者被 Python 的优雅所吸引,可能会陷入编写 “能用 “但缺乏结构完整性的代码的陷阱。他们可能会优先考虑快速的解决方案,而不是长期的可维护性。
代码通过了初始测试,但当部署到生产环境中时,就会暴露出缺陷。简单的假象可能会导致代价高昂的错误,尤其是在项目发展和需求变化的情况下。
新手开发人员经常会陷入这样的陷阱:编写的代码 “能用”,但缺乏结构完整性。就拿这个代码段来说吧:
def divide(a, b):
return a / b
result = divide(10, 0) # Division by zero – a runtime disaster
代码通过了初始测试,但在生产中却会崩溃。简单的假象可能导致代价高昂的错误。
可扩展性问题
随着应用程序的增长,Python 的健壮性问题也变得显而易见。内存管理、并发性和性能都会受到严格审查。Python 的内存占用可能会意外膨胀,影响服务器资源。它的全局解释器锁(GIL)限制了真正的并行性,阻碍了多线程应用。
对于高流量系统来说,Python 的局限性变得非常明显。虽然 Python 在脚本编写和原型开发方面表现出色,但它却难以满足大规模生产级系统的需求。
Go 和 Java 等语言在设计时就考虑到了可扩展性,能为此类场景提供更好的解决方案。
随着项目的增长,Python 的健壮性问题也逐渐显现出来。内存管理和并发性成为瓶颈。例如
# Inefficient memory usage
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
# Try factorial(1000) – stack overflow!
Python 的递归方法会消耗过多内存,因此不适合高流量系统。
GIL 的遗产
全局解释器锁(GIL)是 Python 过去的遗留物,现在仍在困扰着它。GIL 最初是为了线程安全而引入的,它确保每次只有一个线程执行 Python 字节码。
这虽然简化了内存管理,却严重限制了多核利用率。在多核处理器无处不在的今天,Python 的 GIL 成了瓶颈。
开发人员不得不采用多进程等变通方法,这就带来了复杂性和开销。GIL 作为一个遗留问题一直存在,让那些追求真正并行性的人感到沮丧。
import threading
def perform_task():
# Intensive task here
threads = [threading.Thread(target=perform_task) for _ in range(10)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
# Despite creating threads, the GIL limits true parallelism
不一致的语言设计
Python 的设计理念是一把双刃剑。虽然它鼓励创造力和实现目标的多种方法,但也会导致不一致。
不同的库可能会采用不同的约定,让开发者感到困惑。例如字符串格式化:f-strings
、.format()
和连接都是有效的方法。缺乏统一性会影响代码的可读性和可维护性。
相比之下,Kotlin 和 Java 等语言遵守更严格的准则,因此代码库更简洁、更可预测。
例如,实现相同结果的多种方法会导致混乱:
# String formatting options
name = "Alice"
greeting = f"Hello, {name}!"
# Or: greeting = "Hello, {}!".format(name)
# Or: greeting = "Hello, " + name + "!"
这种缺乏统一性的情况妨碍了代码的可读性和可维护性。与 Kotlin 相比,它甚至不是可读的语法。
地狱依赖
Python 的软件包管理可能是一个迷宫。安装第三方软件包的便利是有代价的:依赖冲突。随着项目依赖关系的积累,保持兼容性变得非常具有挑战性。不同的软件包可能需要相同库的冲突版本。
解决这些冲突需要侦查工作、反复试验,有时还需要妥协。即使是经验丰富的开发人员也会陷入臭名昭著的 “依赖地狱”,从而导致挫败感和时间的浪费。它几乎和 JavaScript 一样糟糕。
相互冲突的依赖关系就像一张纠缠不清的网:
# Two packages requiring different versions of the same dependency
import package_a # Requires library X v1.0
import package_b # Requires library X v2.0
# Result: Unpredictable behavior or runtime errors
缺乏现代功能
尽管 Python 广受欢迎,但它在采用现代编程功能方面却常常落后于其他语言。虽然最近的版本引入了类型提示和模式匹配,但其他语言很早就拥有了这些功能。
例如,Scala 的模式匹配多年来一直是主要功能。Python 的缓慢采用率会阻碍创新和生产率,尤其是当开发人员渴望用表现力强的工具来解决复杂问题时。
# Python 3.10 introduced pattern matching
match value:
case 0:
print("Zero")
case _:
print("Non-zero")
# But languages like Scala had this years ago
糟糕的重构支持
重构 Python 代码就像解开一张意大利面条网。它的动态特性使得自动重构工具变得非常谨慎。如果没有严格的类型,这些工具很难准确预测变更的影响。
# Refactoring this function is risky
def process_data(data):
# Process data here
# Manual review and testing become essential
因此,开发人员在重构过程中往往依赖人工审核和大量测试。缺乏强大的重构支持会影响可维护性,并增加引入新错误的风险。
总结
很明显,Python 虽然在某些应用中很容易使用,也很受欢迎,但它充满了挑战,可能会阻碍开发,尤其是当项目的复杂性和规模不断扩大时。
总之,虽然 Python 可以提供一些便利功能,如 Django 管理和人工智能中的易用性,但这些并不能弥补其根本缺陷。对于强大的后端开发而言,开发人员最好使用能提供严格类型、更好性能和更一致设计理念的语言。对于严肃的开发工作来说,设计混乱、缺乏效率的 Python 往往不是最明智的选择。
对于那些寻求更可靠、更可扩展的解决方案的人来说,Kotlin、Java 或 Go 等语言提供了一种更有条理、更注重性能的方法,使它们成为严肃的后端开发的首选。
本文文字及图片出自 Python - a loved, but eternally flawed language
你也许感兴趣的:
- 【外评】Python 为何如此糟糕…
- 【外评】用 Python 解释 Rust 背后的思想或理念
- Python 版本之间的主要变化摘要
- 【外评】Python 与苹果应用商店的拒绝作斗争
- 【外评】使用不安全的 Python 将速度提高 100 倍
- 谷歌裁掉整个 Python 团队!PyTorch 创始人急得直骂人:“WTF!核心语言团队无可替换”
- 谷歌Python团队全员被裁——负责内部Python所有基础设施、曾对数亿行代码执行自动重构
- 再同意不过了
- 【译文】减轻 Python 打包的痛苦
- 【译文】Python 打包,一年之后:回顾 2023 年的 Python 打包
你对本文的反应是: