锁定老帖子 主题:Ruby和Python的语法差别
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-09-27
cookoo 写道 布娃娃在另一个帖子提到很多差别,我觉得和那个主题不符,所以另外开一个贴讨论吧。
其实python和ruby非常接近,比大多数别的语言要接近的多,所以喜欢用啥就用啥(大实话,虽然也是废话)。语法上的差别虽然有那么一点,大部分是syntax sugar,我斗胆稍微列几个(python我也忘得差不多了,不对的大家尽管来鞭尸吧),但是主要差异还是设计思想上的:灵活vs明确. 我不认为两者在生产力上会有什么差别,如果你熟悉的话。*注意,仅限语言本身的比较。 1. ruby的case可以匹配很多东西:范围/数组,对象,正则表达,python没有case/switch而使用if/else比较死板点 2. python的缩进很漂亮,虽然有时会造成些许麻烦。ruby的end蛮难看的,所以大家都被逼当one liner(玩笑) 3. 感觉上ruby比python更OO,当然这也可能是因为python不提倡用那些改变对象内部构造的‘伎俩’造成的错觉 4. python有list comprehension, ruby没有:( 5. python有真正的keyword argument, ruby用hash模拟,当然实际用起来没什么差别 6. python的self很讨厌,ruby没有那种繁琐的东西 7. reflection,ruby内置了很多方法,比如object.methods,而python把这些信息存在特殊的字典里。差不多 8. ruby的block很强,python的lambda只能声明单变量 9. ruby的open class已经声明远播,可以玩出2.days.ago这样的花样,python好像没法直接修改内置类也反对这么做。 10. python需要用@classmethod修饰声明类方法,ruby是内建 11. ruby有单子方法,也就对对象单独定制,python不知道有没有类似概念 12. ruby有method_missing机制,python可以使用__getattr__截获未定义方法(from qiezi) 13. ruby使用单继承+mixin,python使用多重继承,不过python也有mixin 14. ruby有attr_*系列语法helper,省却自己写一堆setter/getter, python的property方法还是得自己写setter/getter 15. ruby和python都使用duck typing,不过python也有一套显式的interface机制(从zope3并入内核了么?) 16. ruby的函数调用括号是可省的,稍微少敲几下键盘。python默认没括号也不带参数的话返回函数本身的一个引用。 17. 我不清楚python的meta programming能到什么程度,只好等大牛来说说了。只是觉得pythoner不常用那个,也许觉得会把程序逻辑搞得晦涩不明。 18. ruby从perl继承了一部分难看的东西,比如很多预定义的$x常量 19. ruby内建正则表达,方便一点 20. ruby的yield是用来call block的。而python的yield是用来给generator输入输出值的。 19. python的库给我感觉命名规范有点不统一,有些方法用snake_case有些则用CamelCase,也许是库太多了遗留下的历史问题 20. python的三引号很漂亮,ruby的<<-XX...XX太难看了,也可以用%q{...}包裹多行文字(from qiezi) 21. ruby的类库设计中喜欢给方法添加别名,方便记忆。 另: ruby官方网站也提供了一些基本的比较。(from Robbin) A说它X,B就笑了;B说它Y,C就笑了…… |
|
返回顶楼 | |
发表时间:2006-09-29
原话可能是 "Smalltalk did that twenty years ago" 和 "Nothing has been invented since Lisp"。
|
|
返回顶楼 | |
发表时间:2006-10-10
cookoo 写道 6. python的self很讨厌,ruby没有那种繁琐的东西
ruby也有self吧,当年理解self.some_method()花了好长时间,不过可能和python中的self不是一个概念…… |
|
返回顶楼 | |
发表时间:2006-10-10
为什么说python要写getter/setter呢?直接赋值不就可以了,又没有保护
|
|
返回顶楼 | |
发表时间:2006-10-10
刑天战士 写道 cookoo 写道 6. python的self很讨厌,ruby没有那种繁琐的东西
ruby也有self吧,当年理解self.some_method()花了好长时间,不过可能和python中的self不是一个概念…… python的self比较冗余,比如 class MyTextWidget(Widget): def __init__(self, master, text="", font="times", color="black"): Widget.__init__(self, master) self.font = self.ui_font(color, font) self.text = text def ui_handle_repair(self, draw, x0, y0, x1, y1): draw.text((0, 0), self.text, self.font) ruby的实例方法不需要用self明确绑定,另外使用@来表示实例变量。 |
|
返回顶楼 | |
发表时间:2006-10-10
Jamsa 写道 为什么说python要写getter/setter呢?直接赋值不就可以了,又没有保护
getter/setter是基本OO封装概念,ruby里局部变量默认全是private的,不写getter/setter就没法访问 |
|
返回顶楼 | |
发表时间:2006-10-10
我说几个ruby让我不爽的地方,pythoner来说说python是不是更好
1。block/proc的区别。概念冗余。而且造成meta-code写起来有障碍。python是不是只有lambda? 2。require不是像java的import一样只输入符号表,而是执行一个文件。更象c的#include。而且require还不能有效检查两个文件是否相同。 3。没有包私有概念。 4。没有一个module loader的概念。一个库的文件之间依赖,还要写require 'mylibname/filename'。这个mylibname很别扭。 5。string不是unicode的。 6。string是mutable的。 |
|
返回顶楼 | |
发表时间:2006-10-11
ajoo 写道 我说几个ruby让我不爽的地方,pythoner来说说python是不是更好
1。block/proc的区别。概念冗余。而且造成meta-code写起来有障碍。python是不是只有lambda? 2。require不是像java的import一样只输入符号表,而是执行一个文件。更象c的#include。而且require还不能有效检查两个文件是否相同。 3。没有包私有概念。 4。没有一个module loader的概念。一个库的文件之间依赖,还要写require 'mylibname/filename'。这个mylibname很别扭。 5。string不是unicode的。 6。string是mutable的。 1. well...python还没block呢 2. python的import是比require自然点,它能理解a.b.c代表嵌套目录,也能用from..import..从一个文件里引入一部分。但总体上python和ruby都不要求一个文件一个类,相比java来说就不需要深度嵌套的目录结构,python的命名域和目录结构之间的关系比ruby更协调自然,而ruby的require和命名域是独立的,可以搞得很复杂。 3. 包私有...ruby可以在module里用private/protected。。。python有个下划线文件名约定,估计是目录中的私有文件吧。 4. 这个python也没有,比如lib/disutils/util.py的开头: import sys, os, string, re from distutils.errors import DistutilsPlatformError from distutils.dep_util import newer from distutils.spawn import spawn from distutils import log 原因同2,因为文件和类不统一,目录和命名域不匹配。某种程度上ruby的require其实管理的是命名域搜索路径而不是命名域本身。极端情况下你可以在不同位置的文件里建立同一命名域下的内容,然后同时require这两个文件结构得到同一个命名域下的东西。我觉得python应该有可能‘感知’同一目录下的别的文件而不用去看一个全局的搜索路径,而ruby很难这么做。 5. 这个可以加$KCODE = 'u'; require 'jcode' 让ruby把string按unicode对待。不过字符串函数还是有问题,最新的rails开发版本有个核心库补丁解决了这个问题,不知道多久才会并入核心库。 |
|
返回顶楼 | |
发表时间:2006-10-11
我现在觉得ruby最郁闷的地方是扩展不方便啊。python有pyrex, ctypes,扩展和包装别的c库都很爽啊。
|
|
返回顶楼 | |
发表时间:2006-10-11
cookoo 写道 4. 这个python也没有,比如lib/disutils/util.py的开头: import sys, os, string, re from distutils.errors import DistutilsPlatformError from distutils.dep_util import newer from distutils.spawn import spawn from distutils import log 原因同2,因为文件和类不统一,目录和命名域不匹配。某种程度上ruby的require其实管理的是命名域搜索路径而不是命名域本身。极端情况下你可以在不同位置的文件里建立同一命名域下的内容,然后同时require这两个文件结构得到同一个命名域下的东西。我觉得python应该有可能‘感知’同一目录下的别的文件而不用去看一个全局的搜索路径,而ruby很难这么做。 2.5之前,对于同一目录里面的文件依赖,python是可以省去distutils的,只是不建议而已,因为写了distutils就更加明确了这个模块的由来. python2.5之后正式引入了相对import,在概念上把饼画圆了。 但是对不同搜索路径下的多个相同命名树,python不会像java一样从多个位置加载,而只是加载第一个位置,后面的被直接无视. |
|
返回顶楼 | |