论坛首页 编程语言技术论坛

Ruby和Python的语法差别

浏览 43288 次
该帖已经被评为精华帖
作者 正文
   发表时间: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就笑了……
0 请登录后投票
   发表时间:2006-09-29  
原话可能是 "Smalltalk did that twenty years ago" 和 "Nothing has been invented since Lisp"。
0 请登录后投票
   发表时间:2006-10-10  
cookoo 写道
6. python的self很讨厌,ruby没有那种繁琐的东西

ruby也有self吧,当年理解self.some_method()花了好长时间,不过可能和python中的self不是一个概念……
0 请登录后投票
   发表时间:2006-10-10  
为什么说python要写getter/setter呢?直接赋值不就可以了,又没有保护
0 请登录后投票
   发表时间: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明确绑定,另外使用@来表示实例变量。
0 请登录后投票
   发表时间:2006-10-10  
Jamsa 写道
为什么说python要写getter/setter呢?直接赋值不就可以了,又没有保护

getter/setter是基本OO封装概念,ruby里局部变量默认全是private的,不写getter/setter就没法访问
0 请登录后投票
   发表时间: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的。
0 请登录后投票
   发表时间: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开发版本有个核心库补丁解决了这个问题,不知道多久才会并入核心库。
0 请登录后投票
   发表时间:2006-10-11  
我现在觉得ruby最郁闷的地方是扩展不方便啊。python有pyrex, ctypes,扩展和包装别的c库都很爽啊。
0 请登录后投票
   发表时间: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一样从多个位置加载,而只是加载第一个位置,后面的被直接无视.
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics