初识python: 惊讶元素
对于已经有其它语言的学习者来说, 开始一门新的语言时, 最需要关注的是那些违反"最小惊讶原则"的东西, 至于其它的一致的东西, 大可以以原来的语言做类比想. 比如, 几乎所有提供printf 的语言都跟C语言库函数中定义的printf 标准一致, 即使这个标准中有很多细节的东西熟练的C程序员也未必知晓, 但它们的符合度是如此之好, 以至于你几乎不必为新语言的printf函数做任何额外的努力, 更进一步来说, 新语言中的printf也许根本没有自己的实现, 只是简单地把任务转手给C的printf函数.
下面是我对 python中让人惊讶的东西的列表:
先说坏消息, 让人厌恶的惊讶
1. 用缩进表示代码结构, 代替了{}, 厌恶度 *********************************************
我几乎出离愤怒了. Eric在他的文章中说他第一眼也很不喜欢这个设计, 但随后就习惯/原谅了它, 我没那么宽容, 也许我永远都不会对它觉得舒适.
Python 从很多其它语言中学到了好的东西, 也从Makfile中学到了要命的, 人见人恨的缩进
我不相信有人会喜欢这个设计, 最多只是能忍受这个设计
2. 行结束符表示一个语句, 分号表示语句的结束符只是可选. 而不是用; 一致地表示语句 厌恶度 ****
一个逻辑行要想在下一行继续, 还得用个 \, 我靠!
3. 标识符命名. 小写字母连写, 厌恶度 *****
我刚开始碰python 就看到了一个函数名 raw_input, 我很欣喜, 我喜欢这种命令方式, 十分醒目, 以至于FxCop 对我的C#代码中这种命名方式提出异议时我也不以为意, 我想我知道什么是可读性, 我也不十分赞同微软的首字母大写单词连写的方案, 但毕竟那个还不至于太坏, 而所有单词全部小写并且连在一起是不可忍受的.
比如python 中的 splitfields
要命的是, 连它的builtin包中的命名都很不一致, 有些命令是好的, 比如 setenv, putenv, 尽量沿用经我不衰的C标准和UNIX传统可以有效保护程序员的既有资产.
4. 在[1:3] 表示的范围中, 包括1, 但不包括3. 厌恶度: ****
a = ['a', 'b', 'c' ]
print a[-1]; #此时显示最后一个元素, 'c'
但
b = a[:-1] #却把最后一个元素排除在外了.
丑陋!
5. print 的最后用,来禁止输入换行符 厌恶度: ***
几乎每个教程中都说, 这种做法很丑陋, 但能工作
6. for/while 后面的else 厌恶度: **
我想不出它有什么实际的用途, 而且要命的是如果循环中有了break, 它还不会被执行, 这使得有些人希望借"它只是一段无论如何都会被执行的代码块" 为简化对它的理解的人又失败了.
7. 字母/hash 表的key 不能是可变对象
比起C#中可以以任意对象作为key 来说, 这个限制太要命了. 如果必需通过对一个类额外做些什么它的实例才能做为hash表的key, 这也是不可接受的, 因为这使本来普通和常用的事情变得不必要的复杂.
至于我不说它慢, 因为我还没有自己体验过到底有多慢.
好的方面:
1. 扔掉了 switch
C 语言对case语句中缺少break 的欣然接受造成无数的bug. C#对这一问题的做法是编译错误, 要么有break, 要么有return.
无论是C#或是 python, 或是perl, 都对这一点做了改进. 虽然各有各的做法. 就个人来说我更喜欢C#的做法.
2. 扔掉了类的public/private可见性控制.
这也许丢了所谓信息隐藏, 但带来的简单性作为补偿, 是好是坏难说
3. 调用函数时允许对指定参数的名字
4. lambda 表达式, 即匿名函数的支持
lisp中最重要的特性, 在用了python中的
print map( lambda x: x**3, [1, 2, 3] )
之后我突然对lisp中的这种代码和数据一视同仁有了一种轻度的认同, 但我对lisp的()还是跟对python的缩进表示代码结构一样厌恶和不习惯.
5. 对任意大小的整数运算的支持.
当然, 很慢.
6. 简单性, 自动内存管理和垃圾收集自不必说了.