作者 | Mohammed Ayar

译者 | 弯月

出品 | CSDN(ID:CSDNnews)

不少人认为 Python 方便掌握,而且不易出错。然而,并非所有人都同意这个观点。

许多高级开发表示,使用动态类型的语言实在很令人头疼:

“什么?动态类型的语言比静态类型的语言更加不容易出错?抱歉,21年的软件开发职业生涯告诉我并不是这样。”

—— Rasmus Schultz

在本文中,我们就来看一看高级开发人员不喜欢动态类型语言的主要原因,同时我也希望通过本文消除大家的误解。

为了更好地挖掘背后的原因,以及鉴于 Python 的广泛普及,我们以 Python 为例来分析一下。

动态类型 

这里所说的动态类型指的是数据类型。

编程语言包含多种类型的风格,比如强类型和鸭子类型等。但是,在本文中我们只讨论两个最常见的类型:

  • 动态类型
  • 静态类型

动态类型指的是在运行时检查类型错误。也就是说不需要显式声明数据类型。Python、Ruby 和 JavaScript 都是这类语言。

与动态类型相反,静态类型则会在编译期间报告类型错误,因此你需要显式声明数据类型。C、C++ 和 Java 就属于这种情况。

一般来说,Python 以及其他编程语言的某些优点也会成为缺点。

动态类型可以通过隐式的数据类型声明减少一部分代码,从而让编程变得更容易。但是,这个特性也有一些缺陷。

请考虑如下 Python 代码:

max_number = 12my_list = []for i in range(1, 5):  max_numbre = 2 * (max_number * i)  my_list.append(max_number)
print(my_list)输出结果:[12, 12, 12, 12]

在这个例子中,我们希望针对变量 max_number 进行一些计算,并将结果存储在列表中。但是,我们可以看到实际的操作并不符合我们的预期,而结果也是错误的。因为在 for 循环中,max_number 的拼写有误,因此导致程序创建了另一个名为 max_numbre 的变量。

任何人都可能犯这样的错误,特别是对于工作压力很大的人。

假设你正在编写一大段代码,那么你必须更加小心手指按下的每一个按键。否则,查找代码中的bug就会成为噩梦,并引发维护性的问题。

然而,在静态类型的语言(比如C++)中,你必须在使用前声明变量。而且你必须在执行代码前进行分析,以确保变量类型匹配。这样你对变量的控制会更有力,因此可以提高安全性。

全局解释器锁

高级开发人员对动态类型语言的另一个质疑是性能。

初级开发人员只需要处理好几行代码,而维护和编写健壮的生产代码(几百行~几千行)的重任一般都由经验丰富的高级开发人员承担。因此,对他们来说,编程语言的效率不容置疑。

由于全局解释器锁(Global Interpreter Lock,即 GIL)的存在,计算机的资源(主要是 CPU 线程数)得不到充分利用,因此它是编程语言(如 Python 和 MRI Ruby 等)的性能瓶颈。

不过,不使用 GIL 的编程语言可以充分利用 CPU 的功能,因为它们支持并行计算。

并行计算只不过是让所有线程同时运行而已。在需要处理的数据量十分庞大时,这种类型的计算会比较有优势。

下图是一个并行计算的示例:

图:所有 CPU 一起运行的示例

我们可以假设,在相同的 CPU 时钟速度下,计算机拥有的线程越多,程序的运行速度就越快。

然而,GIL 的出现终结了并行计算。

GIL 的作用是保证一次只有一个线程使用 GIL。线程的选择遵循排队方式。这意味着,当拥有最高优先级的线程正在使用 GIL 时,其他线程将处于等待状态,直到 GIL 被释放。

最重要的是,用户无法控制线程的选择。只能由操作系统负责线程优先级的排序,如下图所示:

为了解决这个问题,许多程序员都尝试手动在多个线程之间拆分进程,比如 Python 的 multithreading 模块,就是为了获得更好的性能。然而,最终的结果却是性能更差了。

这个结果有点奇怪,如果你想搞清楚事情的始末,则必须再深入研究一下。

尽管 Python 的核心开发团队已经意识到了这个问题,但是想摆脱 GIL 太难了,因为它是许多 Python 功能的基础,例如内存管理和C扩展等等。

Python 的作者 Guido van Rossum 表示,他不确定 Python 是否会支持并行计算,因为这归根结底是语言设计层面的问题。

但是,C++ 等静态类型语言不受 GIL 的限制,因此它们的效率相对更高。

空白的敏感度

错误地使用空白就会报错,并不是每个人都喜欢这样的编程语言。空白不仅包括空格,还包括制表符、换行、返回或换页等。例如,与C不同,Python 对空格就非常敏感。

下面,我们就来比较一下 C 和 Python 代码。

Python 示例:

i = 50if i % 2 == 0:print("inside if statement")  print("i is even")输出结果:print("inside if statement")  print("i is even")                                  ^SyntaxError: invalid syntax

C 示例:

#include<stdio.h>int main(void){int i = 50;if (i % 2 == 0)输出结果:~/ $ ./test1inside if statementi is even

C 的代码结构无论再怎么混乱,都可以得到正确的输出,而 Python 生成的语法错误只是因为语句的书写位置有误。因此,有人可能会说 Python 的健壮性不如 C++ 或 C。

尽管许多专业程序员都认为空白过于敏感很讨人厌,但许多 Python 专家则认为,空白的问题总好过代码长得看不到尽头。

最后,在处理大块代码时,空白的敏感性问题确实很烦人。但是,如果能够向团队灌输良好的编码习惯,则这个问题也很好解决。

向后兼容

不支持向后兼容意味着旧版的 Python 代码无法在新版本中正常工作。换句话说,每当新版本发布时,你都需要找出语法的变化,并重写相应的部分代码。

有时,向后兼容性会成为一个严重的问题,Python 2 到 Python 3 就是一个很好的例子。

Python 核心开发团队认为,将 Python 2 的代码转换成 Python 3 不会有任何问题。但是他们错了。

Python 的作者也承认了这一点:

“我们低估了有多少人已经编写了大量的 Python 代码,而且他们已经基本忘记了代码的工作方式。因此,他们没能很好地升级这些代码。我们已经意识到了这个问题。”

这个问题争论到最后,他们决定延长 Python 2.7 的寿命。

总结

编程语言一直是一个热门话题,这不是一个非黑即白的两极分化问题。我们会因为某些原因而偏爱某一种编程语言。

通常,每种通用编程语言都有特定的适合人群。Python 的官方作者曾说:

“学习使用 Python 编程比学习使用 Java 或 Swift 要容易得多。Java 和 Swift 非常适合计算机科学的专业软件开发人员。但是 Python 更适合孩子的教学。”

话虽如此,我们非常希望能够出现一种兼具C++ 和 Python 优点的编程语言。

原文链接:https://betterprogramming.pub/why-some-senior-developers-dont-like-python-974c5361fff2

声明:本文由CSDN翻译,转载请注明来源。

余下全文(1/3)

本文最初发表在微信公众号,文章内容属作者个人观点,不代表本站立场。

分享这篇文章:

请关注我们:

发表评论

邮箱地址不会被公开。 必填项已用*标注