Python 是一种设计良好且易于使用的编程语言,只要你不问以下问题:为什么必须缩进?为什么末尾不需要分号?为什么是elif而不是else if?奇怪的for-else语法是什么意思?臭名昭著的 GIL 为何存在这么久?为什么所有索引都从 0 开始而不是从 1 开始?这些问题很难回答。它们是出于复杂原因而做出的语言设计决策。大多数情况下,我们只是接受规则并遵循它们。但你好奇为什么吗?本文将满足你的好奇心。
1. 为什么使用缩进来管理 Python 代码块
如果你来自其他主流编程语言,无论是 C/C++、Java、JavaScript/TypeScript、Go 还是其他什么,Python 最不舒服的规则可能是强制缩进。花括号在主流语言中非常常见。但 Python 却与众不同。其官方文件解释了原因:Guido van Rossum 认为,使用缩进进行分组非常优雅,并且大大提高了普通 Python 程序的清晰度。大多数人用过一段时间后就会爱上这个功能。
简单来说,只是因为Python之父做出了这个决定。在我看来,这是一个明智的决定。我最喜欢的一句话是:因为 Python 中的代码块是用缩进来表示的,所以 Python 程序中的缩进是统一的。而且缩进对我们这些读者来说也很有意义。因此,由于我们拥有一致的代码格式,我可以阅读别人的代码,而不会经常被“哦,我明白了。他们把花括号放在这里或那里了。”之类的问题绊倒。我不用费心思考这个问题。本质上,缩进已经成为了 Python 的标志。我们永远不应该指望将来它会被改成花括号。甚至还有一个内置的彩蛋来提醒你这一点。
如果你在 Python 程序中添加以下代码:
一个专门设计的错误信息会告诉你残酷的事实:
不,没有机会!
2.为什么 Python 语句末尾不需要分号
在 C、C++ 和 Java 代码中,分号随处可见。它们使得 在较旧的编译器设计中更容易机械地解析代码。编译器无需猜测语句的结束位置。由于现代编译器足够智能,能够识别语句的结束,因此无需添加不必要的干扰。正如 Python 之禅所说:“简洁胜于复杂”。事实上,这并不是 Python 独有的规则。其他较新的编程语言也正在放弃使用分号作为终止符。
3. Python 为什么有省略号文字
Python 有一个非常特殊的语法,我们可以使用省略号作为不完整代码块的占位符:
Guido van Rossum 清楚地解释了为什么这在 Python 中是可以接受的:有些人认为能够编写 这样的不完整代码会很可爱。
我喜欢这个解释,编程不一定全是逻辑,有时只是因为它很可爱。
4. Python 中的 For-Else 语法有何作用
for-else语法是 Python 中最容易被误解和争议的特性。else 语句块,跟在for语句后面,而不是if语句后面。大多数开发人员根本不认为这是合法的,更不用说实际使用它了。事实上,它的使用出乎意料的简单直接。我们只需要知道:当循环中没有 break 时,for 循环(或 while 循环)后面的块就会运行else这使我们能够编写优雅的搜索式代码来else处理未找到任何内容的情况。
我们看一个适合初学者的例子:
结果显示,很遗憾,Leaders列表中没有Yang,所以循环for没有被打断break。因此,该else块在循环结束后执行。
5.为什么Python使用elif而不是else if
当谈到else关键字时,Python 确实有点奇怪。除了for-else语法之外,Python 还使用elif关键字作为块中else if的if-elif-else缩写。在我看来,让 Python 中的一切都保持整洁和优雅是一个不错的选择。
6.为什么Python没有main()像C或Java那样的函数?
如果你想读懂一个 C 或 Java 程序,你很可能会从它的main()函数开始。因为它是一切的入口,而且必须被定义。但是 Python 并不强制要求main()函数。虽然我们可以像下面这样编写主要逻辑,但它完全是可选的:
为什么?因为 Python 不需要!C/C++、Java 或其他类似语言都是编译型语言,因此代码必须编译成可执行二进制文件。为了帮助操作系统(如果是 C/C++)或 Java 启动器(JVM)找到程序的入口点,需要一个特定的 main 函数。但 Python 是一门解释型语言,代码是自上而下逐行执行的。起始点自然是由代码的执行顺序决定的。因此,main 函数完全是可选的。
7.为什么Python使用基于0的索引
我学的第一门编程语言是 C,然后是 C++,最后是 Python。所以我觉得计算机世界的索引一定是从 0 开始的。直到遇到MATLAB,我才第一次意识到有些语言的索引是从1开始的。然后我的同事告诉我,R、Lua、Fortran、Pascal 和许多其他语言也应用基于 1 的索引。于是我的脑海里出现了一个问题:为什么 Python 选择基于 0 的索引?欢迎评论区讨论。
8. 为什么 Python 有全局解释器锁
Python 太慢了。这是我的经理对我使用 Python 而不是 Java 来开发新的内部基础设施的请求的回复。臭名昭著的全局解释器锁(GIL)确实限制了 Python 在 CPU 密集型任务上的多线程性能。
Python 为什么要通过 GIL 来限制自己?这是一个历史性的问题,Python 诞生于 1991 年 2 月 20 日,比 Java ( 1995 年 5 月 23 日)还要早 4 年。当时,多核或多线程 CPU 并不常见。为了保持简洁高效,Python 的创建者选择实现全局解释器锁 (GIL),这确保了 Python 程序的编写简单且线程安全。但如今,即使是市场上最便宜的 CPU 也是多线程的,这使得 GIL 经常成为批评的对象,因为它限制了 Python 充分利用现代硬件的能力。然而,移除 GIL 并不容易。因为找到一种在不影响单线程性能或向后兼容性的情况下消除 GIL 的方法非常具有挑战性。
好消息是,从 Python 3.13 开始,GIL 将被逐步删除。我们可以安装非 GIL Python 3.13 的实验版本。由于PEP 779的接受,Python 3.14 将正式支持自由线程构建。
9. 为什么 Python 中的==不是is
有两个非常令人困惑的运算符:==和is。乍一看,它们应该是一样的。但这里有一个经典的例子,你可能会有疑问:
:==检查相等性(变量是否具有相同的值?)
is检查身份(它们在内存中是否是完全相同的对象?)
由于 Python 的整数缓存机制,所有 [-5, 256] 范围内的整数都是单例,它们已经保存在内存中。因此,只要我们比较这个范围内的两个变量,is 的结果就会和==的结果相同。但超出这个范围,结果就不同了。写在最后设计编程语言是一门艺术。这当然与创建者的偏见和偏好有关,但像 Python 这样的开源语言也是由整个社区共同构建的。每个设计决策背后都有技术、历史甚至情感方面的原因。虽然有些设计并不完美,有些甚至很奇怪,但我们不能否认Python是一门优雅的语言。
以上就是“9 个 Python 巧妙设计,只有深入了解才能理解”的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://www.phpxs.com/post/13367/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料