波兰开发者 Maciej Kowalski 近日在其个人博客整理了一系列关于 Python 的“怪异”设计。这些特性看似反直觉,实则反映了 Python 作为一门纯面向对象语言的核心哲学——一切皆对象。
Python 比俄罗斯联邦还老。这是文章给出的第一个冷知识。
![]()
Python 诞生于 1991 年 2 月 20 日,而苏联解体发生在同年 12 月 26 日。这意味着 Python 实际上比俄罗斯联邦还要年长近 10 个月。尽管近年来 Python 因人工智能和数据科学的爆发而风靡全球,甚至波兹南工业大学都已用 Python 取代 Delphi 作为教学语言,但它本质上是一门有着 30 多年历史的成熟语言。
更让人感到意外的是,在 Python 中 bool 竟然是 int 的子类。查看 CPython 的 builtins.pyi 定义可以清楚地看到 class bool(int) 这样的继承关系。因此 True + True 的结果是 2,而不是报错。
![]()
这与 Java 等语言形成鲜明对比——Java 中 true + true 会直接触发编译错误。Python 的设计者认为这种多态更加优雅,而且它允许开发者通过继承 int 来创建自定义数值类型。例如,作者展示了一个 modulo10 类,继承自 int 并对加法运算取模,可以直接赋值给 int 类型的变量而不会触发类型检查错误。
class modulo10(int):
def __add__(self, other):
return super().__add__(other) % 10x: int = modulo10(5) # no errors, types match
assert x + 6 == 1# pas
Python 中的 None、True、False 都是单例对象(singleton),在解释器启动时就被创建,垃圾回收器永远不会触碰它们。反复调用 id(None) 会得到完全相同的内存地址。更实用的是小整数缓存机制:CPython 会预先分配 -5 到 256 之间的整数对象。这本质上是计算机科学中经典的 interning 模式,可以显著减少内存分配开销。
文章还提到了一个容易被忽视的陷阱——Python 的循环垃圾回收是可选的。只需四行代码就能人为制造内存泄漏:导入 gc 模块,调用 gc.disable() 禁用循环垃圾回收器,然后创建一个自引用的列表 a = []; a.append(a)。由于 Python 主要依赖引用计数来管理内存,而循环引用会导致引用计数永远无法归零,如果同时关闭了循环垃圾回收器,这段内存就真的泄漏了。
import gc
gc.disable()
a = []
a.append(a)
此外,文章还提到了 GIL(全局解释器锁)这一老生常谈的话题。由于 GIL 的存在,Python 的多线程程序在任意时刻只有一个线程在执行 Python 字节码,无论你的 CPU 有多少核心。对于 I/O 密集型任务,多线程依然有意义;但对于 CPU 密集型任务,多线程不仅无益,甚至可能适得其反。值得庆幸的是,Python 3.13 已经引入了实验性的自由线程模式,未来 GIL 有望被彻底移除。
文章还简要提及了slots内存优化、可变对象作为默认参数的经典陷阱,以及元类(metaclass)等高级特性。这些设计共同构成了 Python“一切皆对象”的语言哲学——函数是对象、类型是对象、甚至类本身也是对象。
参考来源:https://kowal.dev/blog/python-is-weird/
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.