Explore Python's charms by asking WHY questions
Python 为什么?
自从接触到 Python 优雅的语法、流畅的编程体验以及活泼的开源社区后,我就成为了这门语言的忠实粉丝!我阅读了大量的书籍和文章,收获了很多知识,同时也积累了很多自己的思考。
“Python为什么”是一系列文章的合集(含翻译),主要关注 Python 的语法、设计、发展、与其它语言的差别等话题,以一个个“为什么”式的问题为切入点,试着展现 Python 的迷人魅力。
大多数人似乎比较关心“怎么做”(HOW-TO)以及“是什么”(WHAT-IS),因此这类的文章随处可见,同质化极为严重。但是,我更关注的话题是“为什么”(WHY-DO or WHY-NOT-DO),这体现了一种不同的思维方式,它可能偏于务虚,有时候对工作内容不会有实质性的帮助。
回答“为什么”的问题,往往也并非易事,因为一个“为什么”问题的答案通常会引出一个新的“为什么”,最后的答案有可能会走到哲学与美学的范畴,从而出现一种“认同的人完全认同,反对的人坚决反对”的对立局面。最典型的例子就是“为什么 Python 强制使用缩进”,赞同的人(比如我)认为这是 Python 最吸引人的特性之一,而反对的人则会深恶痛绝。
但是,我相信这类问题及回答,有着不可磨灭的重要价值!但愿本仓库收录的话题,能对所有喜爱 Python 和编程的人带来新颖的思考角度,增进自己的编程技艺。
如果你有其它话题建议,欢迎提交 Issue。目前的文章主要是中文,欢迎你来翻译成其它语言的版本,同时,欢迎将翻译后的文件提交 pull request 到本仓库。
赞助&支持
我正在连载 Python 潮流周刊,它精心筛选中英文的 250+ 信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。
欢迎通过项目链接进行了解,如果你喜欢本仓库的内容,我相信你一定会喜欢上这份周刊的!
文章列表
- Python 官方提供了约 30 个常见问题的 FAQ,你可以从中快速得到“权威”的解释- Python 为什么用 len() 函数,不用 x.len() 风格?-and-not-x.len().md)
if name == 'main' 写法,文中给出了我的编程建议
- 编程语言中有好几种变量命名风格,最为流行的两种分别是驼峰命名法和蛇形命名法。本文从编程语言的历史发展过程和语言内部的使用习惯角度,解释了为什么 Python 更偏好于蛇形命名法
- 有过 C/C++/Java 等语言的编程经验的开发者会疑惑,为什么 Python 中没有 i++ 这样的语法
- 这个问题反映出 Python 中的数字对象跟其它语言中的数字有着根本性的差异;另外,Python 的可迭代对象特性,也深刻影响着语言的诸多设计方面
- 很多人以为“a,b=b,a”(交换变量操作)跟“a,b=1,2”(多变量赋值)一样,都是基于元组解包的特性,然而 CPython 的实现并非如此
- CPython 使用专门的优化指令(即 ROTTWO、ROTTHREE 和 ROT_FOUR)实现栈顶元素的快捷交换
- 当同时交换的元素数量大于 4 个时,解释器才会跟“a,b=1,2”(多变量赋值)一样,基于解包实现变量赋值
- 注释符是编程语言中最基础的要素之一,Python 属于“# 号注释符阵营”,原因或许是它遵循着 Shell 等脚本语言的传统
- Python 中不存在“块注释符”,Guido 曾建议使用多行字符串(multi-line strings)来达到块注释的效果,但这种方案在语义上有点怪异
- pass 是 Python 独有的一种空操作,其它语言并没有这样的设计
- pass 可以作为一种空间占位符,辅助程序员快速编程,然而这点小用途并非至关重要的
- 由于 Python 不使用花括号之类的手段来划分代码块,因此在定义空函数时,pass 就成了一种补齐语法逻辑的方案
- ... 是 Python3 在 PEP-3100 中引入的一个内置常量,与 Ellipsis 表示同一个对象
- 官方说它们是单例的,然而这有违事实。要么是文档错了,要么这是一个 Bug ?
- ... 有什么用处,能够解决什么问题?文中介绍了 4 个用途:扩展切片语法、表达“未完成的代码”语义、Type Hint 用法、表示无限循环
- 这也是 Python 与众不同的一个特性,它将其它语言中仅限于布尔类型的操作(if 或 while 或布尔操作 and、or、not),扩展到了任意对象,带来了极大的灵活性
- 真值判断的结果取决于\\bool\\() 和 \\len\\() 这两个魔术方法的返回值
- Python 甚至可以对数字对象作真值判断(表示 0 的数为 False,其它数为 True)
- Python 隐性地为没有带 return 的函数添加一个 return 操作,即默认返回 None 值,这是由解释器强行注入的逻辑。这意味着:Python 中不存在无返回值的函数
- 为什么 Python 要强制令所有函数都有一个返回值呢?为什么它不支持无返回值的空函数呢?
- void 通常指的是一种类型(type),但是它没有具体的值(value)。文中介绍了其它语言需要使用 void 关键字实现的两种功能
- Python 舍弃了表示“没有值的类型”的 void,统一使用表示“仅有一个值的类型” None,配合前一篇“所有函数必然有返回值”的设计,实现了简单好用的效果
- 动静类型与强弱类型是两组不同维度的概念,不应混为一谈。在编程语言发展的早期,当强弱类型的概念还未提出时,一些大佬使用动静类型来笼统地描述语言的特性,这是历史原因
- 如今主流观点以“隐式类型转换”来划分强弱类型,Python 毫无疑问是强类型语言。文中针对几个易混淆的问题,详细解释了为什么 Python 中不存在“隐式类型转换”
- lambda 语法借鉴自 lisp 语言,却遭到 Python 之父的嫌弃,然而它竟从他的屠刀下幸存,这段故事充满戏剧性
- Python 的 lambda 只支持单行表达式,功能不完备。曾有人提议增强 lambda 语法,Python 之父认为那不是好的设计,因而否决了
- Guido 提出要一次性移除 reduce()、map()、filter() 以及 lambda,但最后他妥协了
- 大多数语言都提供了 switch 语句或者极其相似的东西,但在 Python 之父的裁决下,Python 不提供 switch 语句
- 文章介绍了试图引入 switch 语句的 PEP-275 与 PEP-3103,总结了这两个提案的要点以及被否决的原因
- [Python 疑难问题:[] 与 list() 哪个快?为什么快?快多少呢?](./zh_CN/17-why-is-[]-faster-than-list().md)
- 为什么 range() 生成的不是迭代器?-generate-an-iterator.md)
相关资料
- Python文档:关于语言本身的很多问题,都能在文档中找到解答
- Python增强提案:即 PEP,可查找到语言特性的设计、语法及功能的取舍等内容,中文的部分翻译在 PEP中文翻译计划
- Discussions on Python.org:从邮件组升级而来的更好用的论坛,了解社区最新动态
- Guido博客:Python 之父的博客, 介绍了 Python 语言发展历史的部分话题
- Brett Cannon 的系列文章:Python 核心开发者关于语法糖的系列解析,对了解 Python 语法及其实现原理有一定的帮助
Star History
版权声明
全部文章将首发在微信公众号「Python猫」里,欢迎关注:

授权协议:CC BY-NC-SA 4.0