关于python:Python-为什么如此设计

27次阅读

共计 4678 个字符,预计需要花费 12 分钟才能阅读完成。

大略两年半前,我萌发了要创作一个新的系列文章的想法,也就是“Python 为什么”,试图对 Python 的语法及个性提出“为什么”式的问题,以此加深对它的了解,探寻应用技巧、倒退演变、设计哲学等话题。

始终以来,我都是一个有着较强问题意识的充斥着好奇心的人,擅长于辨认出类似货色的差别,并从差异性上发现事物的独特意义。

于是,当将 Python 与其它编程语言作比拟时,加上浏览及翻译了一些 PEP 从而积攒了一些素材后,我就失去了很多的小发现。当确认了国内外的技术社区里短少这方面的文章后,我就更确信了这件事的独特价值。

我过后有个天真的想法,感觉能够依照“十万个为什么”的形式,写出源源不断的文章……

刚开始的 2020 年下半年,我创作力旺盛,写了约 20 篇“Python 为什么”系列文章!然而,到了 2021 年,仅有 2 篇!再到 2022 年,也是仅仅 2 篇!!……

工夫都去哪儿了?怎么我才稍略微偷了个懒儿,它就不见了呢?原本打算有不少想写的话题的,怎么拖着拖着就忘了该怎么写了呢……

最近眼看到了年末,我越想越是有些不甘,于是,花了几天工夫,好好梳理了下“Python 为什么”系列文章,优化了 Github 的介绍内容,筹备认真把这个系列重拾起来!

我把之前考察问卷里遗留的问题,以及其它打算要写的话题放在 Issues 跟踪,欢送大家来提问题 / 给倡议 / 领导写作 / 监督催更……

上面放出的是目前系列文章的介绍,恳请喜爱本系列的同学给颗 star 激励一下!(内容会不断更新 / 增长,请以 Github 主页为准。)

如果你在手机微信端浏览,因为链接跳转麻烦,倡议你通过这个合集的链接进行浏览。

文章列表

  • Python 设计和历史的常见问题

    • Python 官网提供了约 30 个常见问题的 FAQ,你能够从中疾速失去“权威”的解释
  • Python 为什么用 len() 函数,不必 x.len() 格调?-and-not-x.len().md)

    • 介绍了《晦涩的 Python》及 Guido 的解释
    • 我自己认为这体现了 Python 对世界实质的洞察
    • 文章顺便答复了: 为什么 Python 的索引从 0 开始计数?
  • Python 为什么应用缩进来划分代码块?

    • 这是个经典的问题,总会被提起,我总结了 8 个起因
    • 有不少人对上述 8 个起因并不买账,因而我补充了一个回复:Python 的缩进绝不是反人类的设计!
    • Guido 在一次采访中说:严格要求代码缩进的确有点夸大,改用花括号,也不是不能够
    • Python 的缩进起源于 ABC,而 ABC 的缩进起源于 60-70 年代的编程畅想
  • Python 为什么不必分号作语句终止符?

    • 分号个别有分隔符与终止符两种作用,但 Python 只用分号作为分隔符,却不必它作为终止符,而是改用换行作为终止符。本文精炼总结了 5 个起因
  • Python 为什么没有 main 函数?为什么我不举荐写 main 函数?

    • main 函数作为某些编程语言的执行入口是强制必要的,然而 Python 这门脚本语言有着本人更为灵便的执行形式
    • 在我的编程习惯中,我恶感那些不假思索的 if __name__ == '__main__' 写法,文中给出了我的编程倡议
  • Python 为什么举荐蛇形命名法?

    • 编程语言中有好几种变量命名格调,最为风行的两种别离是驼峰命名法和蛇形命名法。本文从编程语言的历史倒退过程和语言外部的应用习惯角度,解释了为什么 Python 更偏好于蛇形命名法
  • Python 为什么不反对 i++ 自增语法,不提供 ++ 操作符?

    • 有过 C/C++/Java 等语言的编程教训的开发者会纳闷,为什么 Python 中没有 i++ 这样的语法
    • 这个问题反映出 Python 中的数字对象跟其它语言中的数字有着根本性的差别;另外,Python 的可迭代对象个性,也深刻影响着语言的诸多设计方面
  • Python 为什么只需一条语句“a,b=b,a”,就能间接替换两个变量?

    • 很多人认为“a,b=b,a”(替换变量操作)跟“a,b=1,2”(多变量赋值)一样,都是基于元组解包的个性,然而 CPython 的实现并非如此
    • CPython 应用专门的优化指令(即 ROT_TWO、ROT_THREE 和 ROT_FOUR)实现栈顶元素的快捷替换
    • 当同时替换的元素数量大于 4 个时,解释器才会跟“a,b=1,2”(多变量赋值)一样,基于解包实现变量赋值
  • Python 为什么用 # 号作正文符?

    • 正文符是编程语言中最根底的因素之一,Python 属于“# 号正文符营垒”,起因或者是它遵循着 Shell 等脚本语言的传统
    • Python 中不存在“块正文符”,Guido 曾倡议应用多行字符串(multi-line strings)来达到块正文的成果,但这种计划在语义上有点怪异
  • Python 为什么要有 pass 语句?

    • pass 是 Python 独有的一种空操作,其它语言并没有这样的设计
    • pass 能够作为一种空间占位符,辅助程序员疾速编程,然而这点小用处并非至关重要的
    • 因为 Python 不应用花括号之类的伎俩来划分代码块,因而在定义空函数时,pass 就成了一种补齐语法逻辑的计划
  • Python 为什么会有个奇怪的“…”对象?

    • … 是 Python3 在 PEP-3100 中引入的一个内置常量,与 Ellipsis 示意同一个对象
    • 官网说它们是单例的,然而这有违事实。要么是文档错了,要么这是一个 Bug?
    • … 有什么用途,可能解决什么问题?文中介绍了 4 个用处:扩大切片语法、表白“未实现的代码”语义、Type Hint 用法、示意有限循环
  • Python 为什么能反对任意的真值判断?

    • 这也是 Python 不同凡响的一个个性,它将其它语言中仅限于布尔类型的操作(if 或 while 或布尔操作 and、or、not),扩大到了任意对象,带来了极大的灵活性
    • 真值判断的后果取决于 \_\_bool\_\_() 和 \_\_len\_\_() 这两个魔术办法的返回值
    • Python 甚至能够对数字对象作真值判断(示意 0 的数为 False,其它数为 True)
  • Python 函数为什么会默认返回 None?

    • Python 隐性地为没有带 return 的函数增加一个 return 操作,即默认返回 None 值,这是由解释器强行注入的逻辑。这意味着:Python 中不存在无返回值的函数
    • 为什么 Python 要强制令所有函数都有一个返回值呢?为什么它不反对无返回值的空函数呢?
  • Python 为什么没有 void 关键字?

    • void 通常指的是一种类型(type),然而它没有具体的值(value)。文中介绍了其它语言须要应用 void 关键字实现的两种性能
    • Python 舍弃了示意“没有值的类型”的 void,对立应用示意“仅有一个值的类型”None,配合前一篇“所有函数必然有返回值”的设计,实现了简略好用的成果
  • Python 为什么是强类型语言,不是弱类型语言?

    • 动静类型与强弱类型是两组不同维度的概念,不应一概而论。在编程语言倒退的晚期,当强弱类型的概念还未提出时,一些大佬应用动静类型来抽象地描述语言的个性,这是历史起因
    • 现在支流观点以“隐式类型转换”来划分强弱类型,Python 毫无疑问是强类型语言。文中针对几个易混同的问题,具体解释了为什么 Python 中不存在“隐式类型转换”
  • Python 之父为什么厌弃 lambda 匿名函数?

    • lambda 语法借鉴自 lisp 语言,却受到 Python 之父的厌弃,然而它竟从他的屠刀下幸存,这段故事充斥戏剧性
    • Python 的 lambda 只反对单行表达式,性能不齐备。曾有人提议加强 lambda 语法,Python 之父认为那不是好的设计,因此否决了
    • Guido 提出要一次性移除 reduce()、map()、filter() 以及 lambda,但最初他斗争了
  • Python 为什么不反对 switch 语句?

    • 大多数语言都提供了 switch 语句或者极其类似的货色,但在 Python 之父的裁决下,Python 不提供 switch 语句
    • 文章介绍了试图引入 switch 语句的 PEP-275 与 PEP-3103,总结了这两个提案的要点以及被否决的起因
  • [Python 疑难问题:[] 与 list() 哪个快?为什么快?快多少呢?](https://github.com/chinesehua…[]-faster-than-list().md)

    • 两种创立列表的 [] 与 list() 写法,哪一个更快呢,为什么它会更快呢?
    • 文章通过字节码与执行过程的剖析,解释了两者执行速度的差别
  • 为什么说 Python 内置函数并不是万能的?

    • 内置函数的名称并不是关键字,而内置作用域位于名称查找的最低优先级,因而在调用时,某些内置函数 / 类型的执行速度就显著慢于它们对应的字面量表示法
  • 为什么继承 Python 内置类型会出问题?!

    • 由《晦涩的 Python》中的例子,引出 Python 在内置类型子类化时不合常理的话题
    • 剖析魔术办法的底层实现逻辑及调用关系,解释内置类型存在的问题
    • 介绍了内置类型子类化的最佳实际
  • 为什么 Python 的 f-string 能够拼接字符串与数字?

    • Python 是强类型语言,在不通过强制类型转换的状况下,字符串无奈拼接数字
    • 介绍了 PEP-498 实现 f-string 的原理
  • Python 的切片为什么不会索引越界?

    • 切片是不少编程语言的个性,Python 的切片不仅功能完善,而且在应用上更为灵便
    • 索引越界是一个常见的问题,Python 切片应用了几条规定,屏蔽了可能导致出错的状况
    • 文章介绍了 Python 的解决方案,然而也留下了一个疑难:为什么 Python 的切片语法要容许索引超出边界呢,为什么不设计成抛出索引谬误?
  • 为什么 range() 生成的不是迭代器?-generate-an-iterator.md)

    • 有很多内置办法能够生成迭代器,然而仿佛只有 range() 生成的是可迭代对象,这个 range() 显得十分独特。文中给出了我对此的猜测
    • 我还留神到 range 是一种不可变序列,然而它跟字符串这种不可变序列相比,也有着独特的体现
  • Python 为什么要保留显式的 self?

    • 这也是一个常见问题。这里给出了官网文档的解释,另外附了 Guido 的一篇博客全文
  • Python 为什么不设计 do-while 循环构造?

    • 在 C/C++、C#、PHP、Java、JavaScript 等语言中,do-while 是一种根本构造。Python 为什么不因循它们的传统呢?有什么非凡的思考?
    • 文章列举了其它语言中 do-while 语法的次要应用场景,解释了为什么 Python 能够不必这种构造
    • 介绍了 PEP-315 试图引入 do-while 构造的尝试,以及 Guido 的拥护意见
  • 为什么 Python 3 把 print 改为函数?

    • Python3 与 Python2 最显眼的一个区别就是:print 语句变成了 print() 函数
    • PEP-3105 Make print a function 是对这个问题最好的答复
  • 为什么说 Python 最会变魔术的魔术办法是它?

    • \_\_missing\_\_() 是仅在内置类型的子类上才存在的魔术办法,仿佛是惟一的特例
    • \_\_missing\_\_() 极为非凡,Python 解释器为它开了后门,实现了最为常见的“魔术办法间调用”逻辑
  • Python 为什么用”elif“,而不是“else if”?

    • elif 写法相比于“else if”更为简洁,这种写法并非 Python 独创。Guido 发推特解释了这种写法的起源

当在两年半前写下第一篇“Python 为什么”系列的时候,我无奈设想本人会在 2023 年到来之际写下这一篇宣告从新起航的小结,更无奈设想是在下一个两年半,或者五年半或者更久,再次写下一篇新的总结。谁说得准呢!

然而,不忘初心,珍惜当下的信心,建立砥砺前行的恒心,我能够的!

最初,别急着划走啊,请肯定记得点个关注、点个 star 哈,喵喵喵~~

正文完
 0