python 系统性的限制了代码的灵活执行,不管是 lambda 还是 eval 都只能运行表达式,应用场景十分有限,极大的限制了 python 语言的表现力。
本来能够很容易就写出来的代码,需要绕弯子。
这种限制在当前没有任何站得住脚的合理解释,非要说就只能扯 pythnoic 意识形态大旗。
python 还有个更糟糕的设计是用缩进当做语法,也许在 30 年前能少敲几下键盘,或者让缩进看起来更一致和美观,但是现在的各种 IDE 全都能自动解决这些问题,根本就不需要人操心。
不过这些设计上的问题总会有些争论的,毕竟大家对自己常用的工具都挺有感情的。
设计是好的还是坏的,到现在是否还合时宜,有个更客观的评价标准,就是那个设计是否影响到了最近才出现的主流语言,如果那个设计是后继无人的,那么必定是坏的。
就拿缩进敏感来说吧,算是典型的后继无人,Swift ? Go ? Rust ? Kotlin ?这种糟糕的设计已经被后人全面抛弃。
python 还有哪些糟糕的设计?
以设计的传承性来看,你可能会发现更多败笔,它们已经被历史无情地扔到垃圾堆中了。
毕竟很多东西都有其时代局限性。

对 Python 不发表意见,不过 Scala 从 2 到 3 是加上了缩进语法块: docs.scala-lang.org/scala3/reference/other-new-features/indentation.html 。

其实我以前还在用 python 时觉得缩进也不是那么另人难受,但转了 js 后发现缩进的确不如 {} 实用

至于 lambda 只有表达式就更糟糕了,用 js 的每个人匿名函数用得飞起,估计让他转用 py 发现不能用了要先定义一个有名函数再传名字估计会一脸懵逼

今天刚碰到一个:isinstance(False, int) = True
我以为我写的是 C😂

楼上的需求应该用 type(False) == int

运行任意代码应该用 exec()

我倒是觉得 python 的缩进语法比 js 的大括号好用,js 写完代码回头去 debug 的时候还得数括号

这个为啥等于 true ,求解释😅

GIL ?

矫情

你可以吐槽 lambda ,但是锁进这个除了古早时代需要用游标卡尺,但是在现代编辑器下早就没有这个问题了

点进来之前我以为会吐槽 type hints , 海象操作符之类的,原来是吐槽这些,打扰了

这些都不是 python 的槽点,python 已经很好用了,比起这些他最大的错误 就是 慢!

你不可能预见到 20-30 年后会发生什么...

GIL

Haskell 缩进敏感
(你如此大胆竟然敢喷 Haskell 的语法?(笑

不是 Python 的语言设计,而是 CPython 的实现细节。PyPy 和 IronPython 我记得都是没有这个机制的,也有人提出了一个提案通过介于函数式和 CoW 的形式来移除 GIL 又能适应 C extension 。

这个论点很早在 Lisp 那边被驳斥过了。括号从来不用数,括号不是给人看的而是帮助语法分析器理解的,正确的缩进才是给人看的。
我非常倾向于认为 JS 的自动代码格式化不应该由括号自动产生缩进,而是应该由缩进自动产生正确的括号。

PyPy 也有 GIL……曾经尝试用 STM 来做一个无 GIL 的版本,然后没有下文了

确实有一点,其实可以混合支持{}和缩进……

(那大概是 Jython 或者别的什么

你的前提可能不太合适,我们不能假设一个语言设计出来就是为了「完美」,少了{}的 python 看起来确实更简洁,有舍有得是常态。不能直接说成重大失误。当然你不喜欢那太正常了,完全合理

缩进做为语法不是问题,
主要是这里是 4 个缩进。而现在流行的是 2 个缩进

本来打了一堆话,后来想想还是全删了,不值得

缩进语法不利于在网络上粘贴分享代码。
而且有了缩进语法,行末却还要写冒号,也是匪夷所思的。

python 最大的问题不是你说的这些,
最大的问题比如:
python2/python3 不兼容,python3 刚出来又没有什么吸引人的特性,导致花费了十来年事件来迁移;
python 设计和 cpython 解释器耦合,导致第三方去掉 gil 、加 jit 等改进必须兼容 cpython ,需要深入 cpython 的实现细节,pypy 到现在兼容性还不太好;
默认参数不能为可变对象,比如 list ,这个问题搞垮了一家创业公司

但编程语言还得看业界需求,设计的好的语言不一定能活得好

我见到的 python go ,Java 代码都是 4 缩进,2 缩进太难看了,只在一些配置文件里看到 2 缩进

2 、3 不兼容真的是大问题(血泪

Python 最大的失误就是 Guido 撂挑子,还跑去了某闭源大厂。

缩进真的是个问题,我看到好多入门的人在学多线程的时候,在循环里开多线程然后 join 一下等待,还疑惑为什么多线程比单线程还慢。后面一看是抄代码的时候因为缩进问题,join 放错位置了。

我觉得作为新手程序员和非程序员的首选语言,强制缩进是 Python 胜出的原因……

最大问题:慢

新手抄代码因为缩进无法运行从而推断语言有问题?

import this 现在看全都是“想得美”

个人认为 Python 就是没个好爹,少给用户一点自由,再 opinionated 一点可以让不少人消停消停。

点进来还以为有高见,结果一半是讲缩进的。

缩进不算什么问题,就像 rust 的简化语法也不是什么问题,问题是执行效率和可阅读性这两者的统一,我认为 python 在这两点上并没有做的很好,倒是在开发效率和简化问题上无可匹敌

Linux 在用 8 缩进,并且认为其他都是异端,而且认为如果 8 缩进放不进 80 列,那么是你的逻辑堆叠层次太多了

别说什么 Python 慢!绝大部分的程序都没有能够触及到 Python 的设计性能瓶颈,跑得慢绝大部分的问题是没写好!

数据是 mutable 的,但是却没有声明关键字

dir(1) == dir(True) == dir(False)有惊喜....

python 的 True 和 False 两个"常量"就是通过两个固定的 longobject 结构体的引用实现的.......

bool 是 int 的子类吧

eval 有限制不是很正常吗

真要灵活性, 用 exec 完全可以达到 eval 的效果啊

这些算个鸡儿失误,GIL 都不说

“默认参数不能为可变对象,比如 list ,这个问题搞垮了一家创业公司”
这个真的是大坑。

用缩进表示结构的另一个主流语言是 Yaml (虽然只是标记语言,不是编程语言)。

彼之砒霜,吾之蜜糖。

要不是我写了三年 python 你说的我就信了
闭包那帖子也是你发的吧,看了那帖子后,看到这个吐槽 python 的我就觉得。不好意思打扰了。

Native Extension 需要和解释器内部实现耦合这个问题 Ruby 也有,其他解释型语言应该也有。解决办法之一就是像 C++或者 JavaScript 这样定个标准,不同实现都按照标准的来,这样 Native 扩展也能有一套统一接口。不过这些脚本语言都是靠一个实现发家的,自己给自己做个 Spec 没啥动力,也不够灵活,所以都拒绝搞标准,实现即标准。

cpython 慢没办法回避的. 看隔壁 ruby 的 mri 从 2.0 开始到 3.0 一直在优化性能, JIT 已经是成了解释器标配.
而 cpython 从 2 升级到 3 解释器性能还是大幅倒退的... 最近 3.10 才总算是比 3.8 快了那么点

GIL !

都来说说林志玲的脸到底哪里最难看

Python 基本上是成也 CPython ,败也 CPython 。

基本上很多核心设计都是为了 glue c extension 而存在的。。。这个嘛,对于 web developer 就是傻逼,对于 data scientist 就是圣经。其他任何语言,包括 ruby, java, c#,哪个比 python 更容易黏合 c/c++ 扩展上机器学习、神经网络的?顶多还有个娘胎中的 julia 。

因为有了 GIL 和引用计数,不需要考虑多线程,是个会写代码的基本都能包装一个 C++ 的算法给 Python 。。。

搞(数学)算法的,大部分人都没有多少编程功底。但是他们能贡献大量算法,才有了今天的数据科学的繁荣。

如果加上 JIT 。。。

看看 pybind11 和 V8 bind 在 C++ 里面的巨大编程难度差别就懂了。。。

燕雀安知鸿鹄之志

你这是本末倒置,缩进是给人看的,括号才是给机器看的。

没有缩进的任何代码,人来看都很费力。

很有道理,所以 Python 除了数据分析和 AI ,搞其他的都是天然劣势。

好家伙,数括号才是最蛋疼的吧

就算用括号,也有自动格式化啊,为什么要数括号?

意思是,既然只有正确缩进了,大家才能看得清,那“缩进”本身就不再是“自由”,本来就是 must 。

而且既然每个语言都有自己的“缩进个数规范”,那本来这也不是“自由”,本来也是 must 。

只不过 python 把这件事放到语言层面规定了下来而已。

所以只是大家不爽它不自由,而不是缩进本来有错。

按你的逻辑,IDE 也有自动缩进辅助啊,也不难写 hhh

那这不是既要又要了嘛,没有银弹的

Ruby 没有这些缺点

就拿缩进敏感来说吧,算是典型的后继无人,Swift ? Go ? Rust ? Kotlin ?这种糟糕的设计已经被后人全面抛弃。

我也觉得,最近在汉化一个 js 项目( CyberChef ),结果人家居然配了 ESLint 规则,缩进不对还过不去,明明都用大括号了还缩进,ESLint 设计 indent 这个规则的人那里肯定有什么大病🐶

其实 Python 也不是不能 lambda 写多行,也不是不能随便缩进(迫真)

def do(*args): return args[-1]

fib = lambda n: do(
 fib_tail := lambda n, a, b: do(
 a if n == 0 else fib_tail(n - 1, b, a + b)
 ),
 fib_tail(n, 0, 1)
)

print(fib(100))

haskell 也缩进敏感, 建议喷 haskell 语法.
无知.

函数式编程的函数本来就只能有一个表达式

缩进最大的问题是格式不统一,有时候 ctrl v 需要一个个对着
有些网站复制代码的时候,缩进会乱掉
(doge)

有了{}也可以有缩进嘛

数 {} 比数 Tap 更省事

不喜欢和重大失误真的不一回事, 至于楼主的其他论点学习只好 #20 了

最让我头疼的还是协程语法不能像线程一样简洁明了(至少能让我 await 自动识别后面的函数是不是协程也行), 平时用协程要给一大堆不知道应不应该 run_in_executor/to_thread 的玩意套娃快烦死了. 但是再难吃也硬着头皮吃下去了

VSCODE 上个月出了个 editor.guides.bracketPairs, 现在配合彩虹缩进和彩虹括号不那么心智负担了

In [10]: isinstance(True, int)
Out[10]: True

In [11]: type(True)
Out[11]: bool

In [12]: issubclass(bool, int)
Out[12]: True

In [13]: True == 1
Out[13]: True

In [14]: False == 0
Out[14]: True

bool 是 int 的子类,,这可能还真是跟 C 语言学的

你不如直接实现一个 Y 组合子,用 lambda 可以编写一切代码。

docs.python.org/3/library/functions.html#:~:text=The%20bool%20class%20is%20a%20subclass%20of%20int

确实可以实现 Y 组合子