python 系统性的限制了代码的灵活执行,不管是 lambda 还是 eval 都只能运行表达式,应用场景十分有限,极大的限制了 python 语言的表现力。
本来能够很容易就写出来的代码,需要绕弯子。
这种限制在当前没有任何站得住脚的合理解释,非要说就只能扯 pythnoic 意识形态大旗。
python 还有个更糟糕的设计是用缩进当做语法,也许在 30 年前能少敲几下键盘,或者让缩进看起来更一致和美观,但是现在的各种 IDE 全都能自动解决这些问题,根本就不需要人操心。
不过这些设计上的问题总会有些争论的,毕竟大家对自己常用的工具都挺有感情的。
设计是好的还是坏的,到现在是否还合时宜,有个更客观的评价标准,就是那个设计是否影响到了最近才出现的主流语言,如果那个设计是后继无人的,那么必定是坏的。
就拿缩进敏感来说吧,算是典型的后继无人,Swift ? Go ? Rust ? Kotlin ?这种糟糕的设计已经被后人全面抛弃。
python 还有哪些糟糕的设计?
以设计的传承性来看,你可能会发现更多败笔,它们已经被历史无情地扔到垃圾堆中了。
毕竟很多东西都有其时代局限性。
1
mind3x 2021-12-02 06:32:33 +08:00 2
对 Python 不发表意见,不过 Scala 从 2 到 3 是加上了缩进语法块: https://docs.scala-lang.org/scala3/reference/other-new-features/indentation.html 。
|
2
makelove 2021-12-02 07:52:18 +08:00
其实我以前还在用 python 时觉得缩进也不是那么另人难受,但转了 js 后发现缩进的确不如 {} 实用
至于 lambda 只有表达式就更糟糕了,用 js 的每个人匿名函数用得飞起,估计让他转用 py 发现不能用了要先定义一个有名函数再传名字估计会一脸懵逼 |
3
xupefei 2021-12-02 07:54:23 +08:00 via iPhone
今天刚碰到一个:isinstance(False, int) = True
我以为我写的是 C😂 |
4
silkriver 2021-12-02 08:19:23 +08:00
楼上的需求应该用 type(False) == int
|
5
silkriver 2021-12-02 08:21:26 +08:00
运行任意代码应该用 exec()
|
6
sudoy 2021-12-02 08:49:31 +08:00 via iPhone
我倒是觉得 python 的缩进语法比 js 的大括号好用,js 写完代码回头去 debug 的时候还得数括号
|
8
pythonee 2021-12-02 09:04:59 +08:00
GIL ?
|
9
adoal 2021-12-02 09:05:19 +08:00
矫情
|
10
Kilerd 2021-12-02 09:08:21 +08:00 via iPhone 12
你可以吐槽 lambda ,但是锁进这个除了古早时代需要用游标卡尺,但是在现代编辑器下早就没有这个问题了
点进来之前我以为会吐槽 type hints , 海象操作符之类的,原来是吐槽这些,打扰了 |
11
chengxiao 2021-12-02 09:12:22 +08:00 1
这些都不是 python 的槽点,python 已经很好用了,比起这些他最大的错误 就是 慢!
|
12
janxin 2021-12-02 09:14:22 +08:00
你不可能预见到 20-30 年后会发生什么...
|
13
lizytalk 2021-12-02 09:16:54 +08:00
GIL
|
14
2i2Re2PLMaDnghL 2021-12-02 09:20:37 +08:00
|
15
adoal 2021-12-02 09:25:17 +08:00
@2i2Re2PLMaDnghL PyPy 也有 GIL……曾经尝试用 STM 来做一个无 GIL 的版本,然后没有下文了
|
16
fgwmlhdkkkw 2021-12-02 09:33:07 +08:00
确实有一点,其实可以混合支持{}和缩进……
|
17
2i2Re2PLMaDnghL 2021-12-02 09:33:18 +08:00
@adoal (那大概是 Jython 或者别的什么
|
18
Vegetable 2021-12-02 09:40:08 +08:00
你的前提可能不太合适,我们不能假设一个语言设计出来就是为了「完美」,少了{}的 python 看起来确实更简洁,有舍有得是常态。不能直接说成重大失误。当然你不喜欢那太正常了,完全合理
|
19
luffy 2021-12-02 09:42:53 +08:00
缩进做为语法不是问题,
主要是这里是 4 个缩进。而现在流行的是 2 个缩进 |
20
zmxnv123 2021-12-02 09:47:11 +08:00
本来打了一堆话,后来想想还是全删了,不值得
|
21
DOLLOR 2021-12-02 09:49:50 +08:00 via Android 2
缩进语法不利于在网络上粘贴分享代码。
而且有了缩进语法,行末却还要写冒号,也是匪夷所思的。 |
22
TypeError 2021-12-02 09:51:38 +08:00 3
python 最大的问题不是你说的这些,
最大的问题比如: python2/python3 不兼容,python3 刚出来又没有什么吸引人的特性,导致花费了十来年事件来迁移; python 设计和 cpython 解释器耦合,导致第三方去掉 gil 、加 jit 等改进必须兼容 cpython ,需要深入 cpython 的实现细节,pypy 到现在兼容性还不太好; 默认参数不能为可变对象,比如 list ,这个问题搞垮了一家创业公司 但编程语言还得看业界需求,设计的好的语言不一定能活得好 |
23
TypeError 2021-12-02 09:53:26 +08:00
@luffy 我见到的 python go ,Java 代码都是 4 缩进,2 缩进太难看了,只在一些配置文件里看到 2 缩进
|
24
mosom 2021-12-02 10:10:42 +08:00
2 、3 不兼容真的是大问题(血泪
|
25
robinlovemaggie 2021-12-02 10:19:11 +08:00
Python 最大的失误就是 Guido 撂挑子,还跑去了某闭源大厂。
|
26
shuimugan 2021-12-02 10:28:50 +08:00 via Android
缩进真的是个问题,我看到好多入门的人在学多线程的时候,在循环里开多线程然后 join 一下等待,还疑惑为什么多线程比单线程还慢。后面一看是抄代码的时候因为缩进问题,join 放错位置了。
|
27
silkriver 2021-12-02 10:35:25 +08:00
我觉得作为新手程序员和非程序员的首选语言,强制缩进是 Python 胜出的原因……
|
28
whywaoxaks 2021-12-02 10:40:03 +08:00
最大问题:慢
|
29
arischow 2021-12-02 10:42:47 +08:00 via iPhone 1
新手抄代码因为缩进无法运行从而推断语言有问题?
|
30
YvesX 2021-12-02 10:43:05 +08:00
import this 现在看全都是“想得美”
|
31
arischow 2021-12-02 10:45:04 +08:00 via iPhone
个人认为 Python 就是没个好爹,少给用户一点自由,再 opinionated 一点可以让不少人消停消停。
|
32
BeautifulSoap 2021-12-02 11:37:28 +08:00 via Android
点进来还以为有高见,结果一半是讲缩进的。
|
33
Huelse 2021-12-02 12:21:47 +08:00
缩进不算什么问题,就像 rust 的简化语法也不是什么问题,问题是执行效率和可阅读性这两者的统一,我认为 python 在这两点上并没有做的很好,倒是在开发效率和简化问题上无可匹敌
|
34
2i2Re2PLMaDnghL 2021-12-02 12:23:47 +08:00
@luffy Linux 在用 8 缩进,并且认为其他都是异端,而且认为如果 8 缩进放不进 80 列,那么是你的逻辑堆叠层次太多了
|
35
ytmsdy 2021-12-02 12:25:15 +08:00
别说什么 Python 慢!绝大部分的程序都没有能够触及到 Python 的设计性能瓶颈,跑得慢绝大部分的问题是没写好!
|
36
Leviathann 2021-12-02 12:33:29 +08:00 via iPhone
数据是 mutable 的,但是却没有声明关键字
|
37
westoy 2021-12-02 13:05:48 +08:00
@15855pm
dir(1) == dir(True) == dir(False)有惊喜.... python 的 True 和 False 两个"常量"就是通过两个固定的 longobject 结构体的引用实现的....... |
39
jjx 2021-12-02 13:15:31 +08:00
eval 有限制不是很正常吗
真要灵活性, 用 exec 完全可以达到 eval 的效果啊 |
40
pmispig 2021-12-02 13:44:06 +08:00
这些算个鸡儿失误,GIL 都不说
|
42
flniu 2021-12-02 13:49:23 +08:00
用缩进表示结构的另一个主流语言是 Yaml (虽然只是标记语言,不是编程语言)。
|
43
kett 2021-12-02 13:57:36 +08:00
彼之砒霜,吾之蜜糖。
|
44
ykk 2021-12-02 13:58:58 +08:00 1
|
45
lingo 2021-12-02 14:17:30 +08:00
闭包那帖子也是你发的吧,看了那帖子后,看到这个吐槽 python 的我就觉得。不好意思打扰了。
|
46
agagega 2021-12-02 14:24:32 +08:00 1
@TypeError
Native Extension 需要和解释器内部实现耦合这个问题 Ruby 也有,其他解释型语言应该也有。解决办法之一就是像 C++或者 JavaScript 这样定个标准,不同实现都按照标准的来,这样 Native 扩展也能有一套统一接口。不过这些脚本语言都是靠一个实现发家的,自己给自己做个 Spec 没啥动力,也不够灵活,所以都拒绝搞标准,实现即标准。 |
47
karloku 2021-12-02 14:34:35 +08:00
cpython 慢没办法回避的. 看隔壁 ruby 的 mri 从 2.0 开始到 3.0 一直在优化性能, JIT 已经是成了解释器标配.
而 cpython 从 2 升级到 3 解释器性能还是大幅倒退的... 最近 3.10 才总算是比 3.8 快了那么点 |
48
betteryjs 2021-12-02 14:41:34 +08:00 via iPhone
GIL !
|
49
SleipniR 2021-12-02 15:03:32 +08:00
都来说说林志玲的脸到底哪里最难看
|
50
ipwx 2021-12-02 15:15:45 +08:00 4
Python 基本上是成也 CPython ,败也 CPython 。
基本上很多核心设计都是为了 glue c extension 而存在的。。。这个嘛,对于 web developer 就是傻逼,对于 data scientist 就是圣经。其他任何语言,包括 ruby, java, c#,哪个比 python 更容易黏合 c/c++ 扩展上机器学习、神经网络的?顶多还有个娘胎中的 julia 。 |
51
ipwx 2021-12-02 15:17:12 +08:00 4
因为有了 GIL 和引用计数,不需要考虑多线程,是个会写代码的基本都能包装一个 C++ 的算法给 Python 。。。
搞(数学)算法的,大部分人都没有多少编程功底。但是他们能贡献大量算法,才有了今天的数据科学的繁荣。 |
52
ipwx 2021-12-02 15:17:52 +08:00
如果加上 JIT 。。。
看看 pybind11 和 V8 bind 在 C++ 里面的巨大编程难度差别就懂了。。。 |
53
pengtdyd 2021-12-02 15:20:02 +08:00
燕雀安知鸿鹄之志
|
54
vanton 2021-12-02 15:28:42 +08:00
你这是本末倒置,缩进是给人看的,括号才是给机器看的。
没有缩进的任何代码,人来看都很费力。 |
55
ninjashixuan 2021-12-02 15:33:19 +08:00
@ipwx 很有道理,所以 Python 除了数据分析和 AI ,搞其他的都是天然劣势。
|
56
deplivesb 2021-12-02 15:36:40 +08:00
好家伙,数括号才是最蛋疼的吧
|
57
kilasuelika 2021-12-02 16:04:48 +08:00
@deplivesb 就算用括号,也有自动格式化啊,为什么要数括号?
|
58
ipwx 2021-12-02 16:52:55 +08:00
@kilasuelika 意思是,既然只有正确缩进了,大家才能看得清,那“缩进”本身就不再是“自由”,本来就是 must 。
而且既然每个语言都有自己的“缩进个数规范”,那本来这也不是“自由”,本来也是 must 。 只不过 python 把这件事放到语言层面规定了下来而已。 所以只是大家不爽它不自由,而不是缩进本来有错。 |
59
ipwx 2021-12-02 16:53:23 +08:00
@kilasuelika 按你的逻辑,IDE 也有自动缩进辅助啊,也不难写 hhh
|
61
Mark24 2021-12-02 17:12:26 +08:00
Ruby 没有这些缺点
|
62
krixaar 2021-12-02 17:29:41 +08:00
>> 就拿缩进敏感来说吧,算是典型的后继无人,Swift ? Go ? Rust ? Kotlin ?这种糟糕的设计已经被后人全面抛弃。
我也觉得,最近在汉化一个 js 项目( CyberChef ),结果人家居然配了 ESLint 规则,缩进不对还过不去,明明都用大括号了还缩进,ESLint 设计 indent 这个规则的人那里肯定有什么大病🐶 |
63
woctordho 2021-12-02 17:31:17 +08:00
其实 Python 也不是不能 lambda 写多行,也不是不能随便缩进(迫真)
```python 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)) ``` |
64
CosimoZi 2021-12-02 18:44:14 +08:00
haskell 也缩进敏感, 建议喷 haskell 语法.
无知. |
65
ruyu 2021-12-02 19:15:54 +08:00
函数式编程的函数本来就只能有一个表达式
|
66
Donahue 2021-12-02 21:01:26 +08:00
缩进最大的问题是格式不统一,有时候 ctrl v 需要一个个对着
有些网站复制代码的时候,缩进会乱掉 (doge) |
68
oOoOoOoOoOo 2021-12-02 21:25:43 +08:00 via Android
@sudoy 数 {} 比数 Tap 更省事
|
69
ClericPy 2021-12-02 21:36:49 +08:00 1
不喜欢和重大失误真的不一回事, 至于楼主的其他论点学习只好 #20 了
最让我头疼的还是协程语法不能像线程一样简洁明了(至少能让我 await 自动识别后面的函数是不是协程也行), 平时用协程要给一大堆不知道应不应该 run_in_executor/to_thread 的玩意套娃快烦死了. 但是再难吃也硬着头皮吃下去了 @sudoy VSCODE 上个月出了个 editor.guides.bracketPairs, 现在配合彩虹缩进和彩虹括号不那么心智负担了 |
70
XIVN1987 2021-12-02 21:54:36 +08:00
@xupefei
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 语言学的 |
71
2i2Re2PLMaDnghL 2021-12-03 10:03:57 +08:00
@woctordho 你不如直接实现一个 Y 组合子,用 lambda 可以编写一切代码。
|
72
void59468 2021-12-03 10:29:05 +08:00
|
73
abersheeran 2021-12-03 14:19:53 +08:00
@2i2Re2PLMaDnghL 确实可以实现 Y 组合子
<script src="https://gist.github.com/abersheeran/80709d4ffd7e83c1206dbcc8df11d4d5.js"></script> |
74
kilasuelika 2021-12-04 17:30:57 +08:00 via Android
@ipwx 我自己用 python 的时候,最烦的就是四个空格和 tab 的区分,还有就是调缩进。
现在慢慢就不用了。我接受 python 应该算早的,高中的时候在智能手机上玩过,但一直不太喜欢。现在主要用 c++,matlab ,mathematica 。 |
75
ipwx 2021-12-04 18:12:55 +08:00
@kilasuelika 可是,所有编辑器都可以直接用空格替代 tab 啊。。。
包括配置 1 tab = 4 spaces 。。。或者 js 就是等于 2 spaces 。IDE 处理 tab 和缩进是很方便的,回车自动缩进其实也不用按 tab 。 |
76
ipwx 2021-12-04 18:13:31 +08:00
还有就是选中一块内容 Shift + Tab 是整体取消一格缩进。。。 也都是 IDE 的基本功能
|
77
kilasuelika 2021-12-04 20:33:46 +08:00 via Android
@ipwx 你这个太理想化了,写代码的时候不一定总是用同一个 ide ,大多数时候都不会用 ide 。可能是打开记事本写,可能是打开 notepad++,有时候又是在 jupyter notebook 中写,有时 vs code ,有时就直接在终端里面写。
|
78
ipwx 2021-12-04 23:27:19 +08:00
@kilasuelika 但是你以己度人了。
事实上我写代码从来都用 IDE ,无论是六万行 C++ ( CLion )还是 pytorch 模型( Pycharm )。Jupyter 我基本上只是在服务器上起 Jupyter Lab 用它的终端,实际写模型还是在 Pycharm 里面,打开它的 ssh 自动同步功能,修改的代码就自动上传到服务器了。 然后我当年实验室里面,二十几台服务器我配的,有共享文件系统。这样的好处是,在自己笔记本上修改了代码,瞬间可以在 20 几台服务器(其中四台 GPU ,共 20 几张显卡)的服务器上同时开多个实例调参数——你只是在各个不同服务器上的 Jupyter lab terminal 里面操作而已。这不比一个 Jupyter notebook 强太多了吗? 此外就是,我当年做研究,代码也是有层次、整理成工程的。甚至我自己都有一套自己的 tensorflow 组件库(后来是 pytorch ),可以 pip install 的。实验室不下十篇论文引用了我的组件库。 而且哪怕不是像我这样工程能力比较强的,遵照我的 workflow ,用起来也很爽。就是参考我上面说的,本地笔记本用 IDE 改好以后,瞬间就同步到二十几台服务器上了。真在截稿前 ddl 疯狂跑参数的时候,这实在太重要了。 啊顺便我自己有一套参数保存、读取和命令行读取的库。这样的话一个 .py 可以瞬间人肉调参十几组同时跑。这也是大前提。 |
79
ipwx 2021-12-04 23:30:10 +08:00
@kilasuelika 当然后来做公司项目了,那还是必然差不多还是 IDE 优先 hhh 。反正真的上传代码都是 git push ,部署有 CI 。综上,无论是研究性代码,还是工程性代码,其实 IDE 效率都远高于单独用 Jupyter notebook 或者 vscode 。
|
80
ipwx 2021-12-04 23:33:16 +08:00
@kilasuelika 说起来当年我做一篇论文,曾经有过最多 20 个实验在跑:四个数据集、每组各 12 个参数的组合,一个大表需要跑。那更是不可能复制 50 个 .py 文件或者 50 个 Jupyter Notebook 呗。只能按照我的工作流,实验代码项目化,IDE 里面自动同步到服务器(有共享文件系统,所以同步到任何一台服务器,等于同步到所有服务器)。
然后超参都通过命令行给,每台服务器还当时用了 Dask Scheduler ,一个好了就启动下一个。基本都是第一天挂上,第二天看结果。。。。 我还写了个 Vue.js 的结果收集页面 hhh |
82
AX5N 2021-12-05 15:34:40 +08:00
缩进敏感是个伟大的文明
|
83
kilasuelika 2021-12-06 01:57:18 +08:00 via Android
@ipwx 哈哈那你很厉害呀👍🏻,项目管理确实重要,不然很容易就搞乱了。
|
84
O5oz6z3 2021-12-06 16:30:17 +08:00
你是对的,这个语言就和它的名字一样,是个喜剧 /笑话。
|
85
O5oz6z3 2021-12-08 13:32:16 +08:00
看到英文维基上在传播 #Languages_influenced_by_Python 的胡说八道,我气得浑身发抖手脚冰凉(入冬),英文互联网还能不能好了?
|
87
ipwx 2021-12-11 23:23:43 +08:00
@c0xt30a 啥玩意儿的代码?
我论文代码: https://github.com/NetManAIOps/Donut 我后来整理出来的一些模型代码: https://github.com/haowen-xu/tfsnippet |
88
ipwx 2021-12-11 23:25:16 +08:00
@c0xt30a 哦你说跑实验的代码?
https://github.com/haowen-xu/ml-essentials https://github.com/haowen-xu/mlstorage-server 不过这两个相对而言没怎么写好文档。。。 |