Ruby有什么不Python的,反之亦然?

Python和Ruby之间有很多讨论,我都觉得它们完全没有帮助,因为它们都回避了为什么特性X在语言Y中很糟糕,或者声明语言Y没有X,尽pipe事实上它确实如此。 我也知道为什么我更喜欢Python,但这也是主观的,并不会帮助任何人select,因为他们可能没有像我一样的开发口味。

客观地列出这些差异是很有趣的。 所以没有“Python的lambda吮吸”。 相反,请解释一下Ruby的lambdaexpression式可以做到Python不能做的事情。 没有主观性。 示例代码很好!

请不要在一个答案中有几处不同。 并且把你知道的那些正确的投下来,然后把那些你知道的不正确的(或者是主观的)投下来。 而且,语法上的差异也不是很有趣。 我们知道Python会使用括号括起来的缩进,并且在Python中@被称为self。

更新:现在这是一个社区维基,所以我们可以在这里添加大的差异。

Ruby在类体中有一个类引用

在Ruby中,您已经在类体中引用了类(self)。 在Python中,只有在类构造完成之后,才能引用该类。

一个例子:

class Kaka puts self end 

在这种情况下,自己是class级,这个代码会打印出“卡卡”。 没有办法打印出类名或以其他方式从Python中的类定义主体(外部方法定义)访问类。

所有的类在Ruby中都是可变的

这使您可以开发核心类的扩展。 这是一个轨道扩展的例子:

 class String def starts_with?(other) head = self[0, other.length] head == other end end 

Python(想象没有''.startswith方法):

 def starts_with(s, prefix): return s[:len(prefix)] == prefix 

你可以在任何序列上使用它(不只是string)。 为了使用它,你应该明确地导入它,例如, from some_module import starts_with

Ruby具有像Perl一样的脚本function

Ruby具有一stream的正则expression式,$ -variables,awk / perl逐行input循环以及其他特性,使得它更适合编写embedded文本文件的小型shell脚本,或者作为其他程序的粘合代码。

Ruby有一stream的延续

感谢callcc声明。 在Python中,您可以通过各种技术创build延续,但不支持内置的语言。

ruby有块

使用“do”语句,您可以在Ruby中创build一个多行匿名函数,它将作为参数传入到do前面的方法中,并从那里调用。 在Python中,您可以通过传递方法或使用生成器来完成此操作。

ruby:

 amethod { |here| many=lines+of+code goes(here) } 

Python(Ruby块对应于Python中的不同构造):

 with amethod() as here: # `amethod() is a context manager many=lines+of+code goes(here) 

要么

 for here in amethod(): # `amethod()` is an iterable many=lines+of+code goes(here) 

要么

 def function(here): many=lines+of+code goes(here) amethod(function) # `function` is a callback 

有趣的是,Ruby中用于调用块的便利语句被称为“yield”,在Python中将创build一个生成器。

ruby:

 def themethod yield 5 end themethod do |foo| puts foo end 

python:

 def themethod(): yield 5 for foo in themethod(): print foo 

虽然原理不同,但结果却非常相似。

Ruby更容易支持函数式(pipe道式)编程

 myList.map(&:description).reject(&:empty?).join("\n") 

python:

 descriptions = (f.description() for f in mylist) "\n".join(filter(len, descriptions)) 

Python有内置的生成器(像上面提到的那样使用Ruby块)

Python支持语言中的生成器。 在Ruby 1.8中,您可以使用生成器模块,使用continuation从块创build生成器。 或者,你可以使用块/ proc / lambda! 而且,在Ruby 1.9中,Fibers是可以用作生成器的,Enumerator类是一个内置的生成器4

docs.python.org有这个生成器的例子:

 def reverse(data): for index in range(len(data)-1, -1, -1): yield data[index] 

与上面的块示例对比。

Python具有灵活的名称空间处理

在Ruby中,当你导入一个带有require的文件时,在这个文件中定义的所有东西都将在你的全局命名空间中结束。 这会导致命名空间污染。 解决scheme是Rubys模块。 但是,如果使用模块创build名称空间,则必须使用该名称空间来访问所包含的类。

在Python中,该文件是一个模块,您可以使用from themodule import *导入其包含的名称,从而如果需要的话会污染名称空间。 但是,您也可以使用from themodule import aname, another导入选定的名称from themodule import aname, another或者只需import themodule ,然后使用import themodule访问名称。 如果你想在你的命名空间中有更多的级别,你可以使用包,它们是模块目录和一个__init__.py文件。

Python有文档

文档string是附加到模块,函数和方法的string,可以在运行时进行内省。 这有助于创build诸如帮助命令和自动文档之类的东西。

 def frobnicate(bar): """frobnicate takes a bar and frobnicates it >>> bar = Bar() >>> bar.is_frobnicated() False >>> frobnicate(bar) >>> bar.is_frobnicated() True """ 

Ruby的等价物与javadocs类似,位于方法之上,而不是在方法之内。 通过使用1.9的Method#source_location 示例使用,可以在运行时从文件中检索它们

Python有多重inheritance

Ruby没有(“故意” – 请参阅Ruby的网站, 在这里看到它是如何在Ruby中完成的 )。 它确实将模块概念重用为一种抽象类。

Python有list / dict理解

python:

 res = [x*x for x in range(1, 10)] 

ruby:

 res = (0..9).map { |x| x * x } 

python:

 >>> (x*x for x in range(10)) <generator object <genexpr> at 0xb7c1ccd4> >>> list(_) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

ruby:

 p = proc { |x| x * x } (0..9).map(&p) 

Python 2.7+

 >>> {x:str(y*y) for x,y in {1:2, 3:4}.items()} {1: '4', 3: '16'} 

ruby:

 >> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}] => {1=>"4", 3=>"16"} 

Python有装饰器

类似于装饰器的东西也可以在Ruby中创build,也可以认为它们不像Python那样必要。

语法差异

Ruby需要“结束”或“}”来closures所有的作用域,而Python只使用空白。 最近在Ruby中尝试只允许空格缩进http://github.com/michaeledgar/seamless

Ruby有的概念,它们本质上是一段代码中的句法糖; 他们是一种创build闭包并将其传递给另一种可能或不可能使用该块的方法。 稍后可以通过yield语句调用一个块。

例如, Arrayeach方法的简单定义可能是这样的:

 class Array def each for i in self yield(i) # If a block has been passed, control will be passed here. end end end 

那么你可以这样调用它:

 # Add five to each element. [1, 2, 3, 4].each{ |e| puts e + 5 } > [6, 7, 8, 9] 

Python有匿名函数/闭包/ lambdas,但它没有块,因为它缺less一些有用的语法糖。 但是,至less有一种方法可以用专门的方式来实现。 例如,看这里

Python示例

函数是Python中的第一类variables。 你可以声明一个函数,把它作为一个对象传递,并覆盖它:

 def func(): print "hello" def another_func(f): f() another_func(func) def func2(): print "goodbye" func = func2 

这是现代脚本语言的基本特征。 JavaScript和Lua也是这样做的。 Ruby不会这样处理函数。 命名一个函数调用它。

当然,在Ruby中有办法做这些事情,但它们不是一stream的操作。 例如,你可以用Proc.new封装一个函数,把它作为一个variables来处理 – 但是这不再是一个函数; 这是一个“调用”方法的对象。

Ruby的函数不是一stream的对象

Ruby函数不是一stream的对象。 函数必须包装在一个对象中以传递它们; 所产生的对象不能像一个函数一样对待。 函数不能以一stream的方式分配; 相反,必须调用其容器对象中的函数来修改它们。

 def func; p "Hello" end def another_func(f); method(f)[] end another_func(:func) # => "Hello" def func2; print "Goodbye!" self.class.send(:define_method, :func, method(:func2)) func # => "Goodbye!" method(:func).owner # => Object func # => "Goodbye!" self.func # => "Goodbye!" 

最终,所有的答案在某个层次上都是主观的,到目前为止发布的答案几乎certificate,你不能指向任何一种在其他语言中无法实现的特性, ,因为这两种语言都非常简洁和富有performance力。

我喜欢Python的语法。 但是,您必须深入一点,才能findRuby的真正之美。 Ruby的一致性中有着禅意的美。 尽pipe没有一个微不足道的例子可以完全解释,但我会试着在这里提出一个解释我的意思。

反转这个string中的单词:

 sentence = "backwards is sentence This" 

当你考虑如何做,你会做以下几点:

  1. 把这个句子分解成单词
  2. 翻转单词
  3. 将单词重新joinstring

在Ruby中,你可以这样做:

 sentence.split.reverse.join ' ' 

正如你想的那样,按同样的顺序,一个接一个的方法。

在Python中,它看起来更像这样:

 " ".join(reversed(sentence.split())) 

这不难理解,但并不完全一样。 主题(句子)被埋在中间。 操作是function和对象方法的混合。 这是一个微不足道的例子,但是在真正处理和理解Ruby时,发现了许多不同的例子,特别是在非平凡的任务中。

Python有一个“我们都在这里大人”的心态。 因此,你会发现Ruby有常量,而Python没有(尽pipeRuby的常量只会引发警告)。 Python的思维方式是,如果你想使某些东西保持不变,你应该把variables名放在所有大写字母中,而不要改变它。

例如,Ruby:

 >> PI = 3.14 => 3.14 >> PI += 1 (irb):2: warning: already initialized constant PI => 4.14 

python:

 >>> PI = 3.14 >>> PI += 1 >>> PI 4.1400000000000006 

你只能从Python模块中导入特定的函数。 在Ruby中,您可以导入整个方法列表。 你可以用Ruby来“卸载”它们,但这不是它的全部。

编辑:

让我们来看看这个Ruby模块:

 module Whatever def method1 end def method2 end end 

如果你把它包含在你的代码中:

 include Whatever 

你会看到方法1和方法2都被添加到你的名字空间。 您不能只导入方法1。 您既可以导入它们,也可以不导入它们。 在Python中,您只能导入您select的方法。 如果这将有一个名字,也许它会被称为select性导入?

从Ruby的网站 :

相似之处和Python一样,在Ruby中,…

  • 有一个交互式提示(称为irb)。
  • 您可以在命令行上阅读文档(使用ri命令而不是pydoc)。
  • 没有特殊的行结束符(除了通常的换行符)。
  • string文字可以像Python的三引号string一样跨越多行。
  • 括号是用于列表的,括号是用于字典的(在Ruby中被称为“哈希”)。
  • 数组的工作原理是相同的(添加它们使得一个长数组,但是像这样组成它们a3 = [ a1, a2 ]给你一个数组数组)。
  • 对象是强烈而dynamic的types。
  • 一切都是一个对象,variables只是对象的引用。
  • 虽然关键字有点不同,但exception工作大致相同。
  • 你有embedded式文档工具(Ruby的被称为rdoc)。

差异与Python不同,在Ruby中,…

  • string是可变的。
  • 你可以创build常量(你不打算改变的variables)。
  • 有一些强制性的case-conventions(例如类名以大写字母开头,variables以小写字母开头)。
  • 只有一种列表容器(一个数组),它是可变的。
  • 双引号string允许转义序列(如\ t)和一个特殊的“expression式replace”语法(它允许您直接将Rubyexpression式的结果插入到其他string中,而无需“添加”+“string”+“在一起”) 。 单引号string就像Python的“原始string”。
  • 没有“新风格”和“旧风格”的课程。 只是一种。
  • 你永远不会直接访问属性。 使用Ruby,这是所有的方法调用。
  • 方法调用的括号通常是可选的。
  • 有公开的,私有的,受保护的,以强制访问,而不是Python的_voluntary_ underscore __convention__
  • 用“mixin”代替多重inheritance。
  • 您可以添加或修改内置类的方法。 这两种语言都可以让你在任何时候打开和修改类,但是Python可以防止内置的修改 – Ruby不会。
  • 你有true和false而不是True和False(而不是None)。
  • 当对真相进行testing时,只有虚假和无虚拟价值。 其他一切都是真实的(包括0,0.0,“”和[])。
  • 这是elifif而不是elif。
  • 这是需要而不是import。 否则,用法是一样的。
  • 上面的东西(而不是下面的docstrings)上的常见样式的注释用于生成文档。
  • 有一些捷径,虽然给你更多的记忆,你很快就会学习。 他们倾向于使Ruby变得有趣并且非常有效率。

Ruby对Python的支持是它的脚本语言function。 脚本语言在这种情况下意味着用于shell脚本中的“粘合代码”和一般的文本操作。

这些大部分与Perl共享。 一stream的内置正则expression式,$ -Variables,有用的命令行选项,如Perl(-a,-e)等

再加上它简洁而又不失代表性的语法,对于这些任务来说是完美的。

Python对我来说更多的是一种dynamictypes的商业语言,它非常容易学习,并且语法简洁。 不像Ruby那么“酷”,但整洁。 Python对Ruby有什么是其他库的大量绑定。 绑定到Qt和其他GUI库,许多游戏支持库和和。 Rubyless得多。 虽然很多使用绑定,例如数据库质量好,我发现利基库更好地支持在Python中,即使在同一个库也有一个Ruby绑定。

所以,我会说两种语言都有其用处,而且它的任务是定义使用哪一种语言。 两者都很容易学习。 我并排使用它们。 用于脚本的Ruby和用于独立应用程序的Python。

我不认为“Ruby有X和Python不是,而Python有Y和Ruby不是”是最有用的方式来看待它。 他们语言非常相似,有许多共同的能力。

在很大程度上,区别在于语言的优雅和可读性。 要使用你提出的一个例子,两者在理论上都有lambdaexpression式,但是Python程序员倾向于避免它们,而使用它们的结构看起来并不像Ruby中那样可读或惯用。 所以在Python中,一个好的程序员会想要采取不同的途径来解决这个问题,而不是他在Ruby中的问题,只是因为它实际上更好的方法。

我想提出一个原始问题的变体,“Ruby不具有Python,反之亦然? 它承认了一个令人失望的答案,“那么,你可以用Ruby或Python做什么,在Intercal中是做不到的? 在这个层面上什么都没有,因为Python和Ruby都是庞大的王室的一部分,坐在图灵近似的宝座上。

但是这个怎么样:

在Python中,如何在Ruby中使用这样的美观和良好的工程,无法做到这一点,反之亦然呢?

这可能比单纯的function比较更有趣。

Python有一个明确的内置语法,用于列表和全局生成器,而在Ruby中,则使用映射和代码块。

比较

 list = [ x*x for x in range(1, 10) ] 

 res = (1..10).map{ |x| x*x } 

“以大写字母开头的variables变成常量,不能修改”

错误。 他们能。

你只会得到一个警告,如果你这样做。

在基础设施方面更多一些:

  • Python比C ++(通过像Boost.Python , SIP和Py ++这样的事情)要好得多,这个选项似乎要么直接写在Ruby解释器API上(当然你也可以用Python来编写)但是在这两种情况下这样做是低级的,单调乏味的和容易出错的),或者使用SWIG(尽pipe它起作用,而且如果你想要支持很多语言,那肯定是非常棒的),如果不是像Boost.Python或者SIP那样好的话你是专门寻找绑定C + +)。

  • Python有许多Web应用程序环境(Django,Pylons / Turbogears,web.py,可能至less有六十多个),而Ruby(有效)有一个:Rails。 (其他Ruby Web框架确实存在,但看起来很难获得对Rails的强大支持)。 这方面是好还是坏? 很难说,也许很主观; 我可以很容易地想象出Python的情况更好,Ruby的情况更好。

  • 在文化上,Python和Ruby社区似乎有些不同,但我只能暗示这一点,因为我没有太多与Ruby社区交互的经验。 我主要是希望能够有一个经验丰富的人能放大(或拒绝)这个陈述。

Alex Martelli从comp.lang.python邮件列表中回答“ Ruby比Python更好 ”的主题。

2003年8月18日上午10:50 Erik Max Francis写道:

“Brandon J. Van Every”写道:

Ruby比Python好什么? 我确定有什么 它是什么?

问问Ruby这个人,而不是Python的人会更有意义吗?

例如,如果某个人的目的包括了Python社区的“社会学研究”,那么可能或者可能不会,那么向该社区提出问题可能会更多地揭示关于它的信息,而不是放在其他地方:-)。

就我个人而言,我很高兴在OSCON的最后一次使用Dave Thomas的一天Ruby教程。 在语法差异的薄弱之处,我发现Ruby和Python非常相似 – 如果我计算几乎所有语言中的最小生成树,我很确定Python和Ruby将成为合并的前两个叶子一个中间节点:-)。

Sure, I do get weary, in Ruby, of typing the silly "end" at the end of each block (rather than just unindenting) — but then I do get to avoid typing the equally-silly ':' which Python requires at the start of each block, so that's almost a wash:-). Other syntax differences such as '@foo' versus 'self.foo', or the higher significance of case in Ruby vs Python, are really just about as irrelevant to me.

Others no doubt base their choice of programming languages on just such issues, and they generate the hottest debates — but to me that's just an example of one of Parkinson's Laws in action (the amount on debate on an issue is inversely proportional to the issue's actual importance).

Edit (by AM 6/19/2010 11:45): this is also known as "painting the bikeshed" (or, for short, "bikeshedding") — the reference is, again, to Northcote Parkinson, who gave "debates on what color to paint the bikeshed" as a typical example of "hot debates on trivial topics". (end-of-Edit).

One syntax difference that I do find important, and in Python's favor — but other people will no doubt think just the reverse — is "how do you call a function which takes no parameters". In Python (like in C), to call a function you always apply the "call operator" — trailing parentheses just after the object you're calling (inside those trailing parentheses go the args you're passing in the call — if you're passing no args, then the parentheses are empty). This leaves the mere mention of any object, with no operator involved, as meaning just a reference to the object — in any context, without special cases, exceptions, ad-hoc rules, and the like. In Ruby (like in Pascal), to call a function WITH arguments you pass the args (normally in parentheses, though that is not invariably the case) — BUT if the function takes no args then simply mentioning the function implicitly calls it. This may meet the expectations of many people (at least, no doubt, those whose only previous experience of programming was with Pascal, or other languages with similar "implicit calling", such as Visual Basic) — but to me, it means the mere mention of an object may EITHER mean a reference to the object, OR a call to the object, depending on the object's type — and in those cases where I can't get a reference to the object by merely mentioning it I will need to use explicit "give me a reference to this, DON'T call it!" operators that aren't needed otherwise. I feel this impacts the "first-classness" of functions (or methods, or other callable objects) and the possibility of interchanging objects smoothly. Therefore, to me, this specific syntax difference is a serious black mark against Ruby — but I do understand why others would thing otherwise, even though I could hardly disagree more vehemently with them:-).

Below the syntax, we get into some important differences in elementary semantics — for example, strings in Ruby are mutable objects (like in C++), while in Python they are not mutable (like in Java, or I believe C#). Again, people who judge primarily by what they're already familiar with may think this is a plus for Ruby (unless they're familiar with Java or C#, of course:-). Me, I think immutable strings are an excellent idea (and I'm not surprised that Java, independently I think, reinvented that idea which was already in Python), though I wouldn't mind having a "mutable string buffer" type as well (and ideally one with better ease-of-use than Java's own "string buffers"); and I don't give this judgment because of familiarity — before studying Java, apart from functional programming languages where all data are immutable, all the languages I knew had mutable strings — yet when I first saw the immutable-string idea in Java (which I learned well before I learned Python), it immediately struck me as excellent, a very good fit for the reference-semantics of a higher level programming language (as opposed to the value-semantics that fit best with languages closer to the machine and farther from applications, such as C) with strings as a first-class, built-in (and pretty crucial) data type.

Ruby does have some advantages in elementary semantics — for example, the removal of Python's "lists vs tuples" exceedingly subtle distinction. But mostly the score (as I keep it, with simplicity a big plus and subtle, clever distinctions a notable minus) is against Ruby (eg, having both closed and half-open intervals, with the notations a..b and a…b [anybody wants to claim that it's obvious which is which?-)], is silly — IMHO, of course!). Again, people who consider having a lot of similar but subtly different things at the core of a language a PLUS, rather than a MINUS, will of course count these "the other way around" from how I count them:-).

Don't be misled by these comparisons into thinking the two languages are very different, mind you. They aren't. But if I'm asked to compare "capelli d'angelo" to "spaghettini", after pointing out that these two kinds of pasta are just about undistinguishable to anybody and interchangeable in any dish you might want to prepare, I would then inevitably have to move into microscopic examination of how the lengths and diameters imperceptibly differ, how the ends of the strands are tapered in one case and not in the other, and so on — to try and explain why I, personally, would rather have capelli d'angelo as the pasta in any kind of broth, but would prefer spaghettini as the pastasciutta to go with suitable sauces for such long thin pasta forms (olive oil, minced garlic, minced red peppers, and finely ground anchovies, for example – but if you sliced the garlic and peppers instead of mincing them, then you should choose the sounder body of spaghetti rather than the thinner evanescence of spaghettini, and would be well advised to forego the achovies and add instead some fresh spring basil [or even — I'm a heretic…! — light mint…] leaves — at the very last moment before serving the dish). Ooops, sorry, it shows that I'm traveling abroad and haven't had pasta for a while, I guess. But the analogy is still pretty good!-)

So, back to Python and Ruby, we come to the two biggies (in terms of language proper — leaving the libraries, and other important ancillaries such as tools and environments, how to embed/extend each language, etc, etc, out of it for now — they wouldn't apply to all IMPLEMENTATIONS of each language anyway, eg, Jython vs Classic Python being two implementations of the Python language!):

  1. Ruby's iterators and codeblocks vs Python's iterators and generators;

  2. Ruby's TOTAL, unbridled "dynamicity", including the ability
    to "reopen" any existing class, including all built-in ones, and change its behavior at run-time — vs Python's vast but bounded dynamicity, which never changes the behavior of existing built-in classes and their instances.

Personally, I consider 1 a wash (the differences are so deep that I could easily see people hating either approach and revering the other, but on MY personal scales the pluses and minuses just about even up); and 2 a crucial issue — one that makes Ruby much more suitable for "tinkering", BUT Python equally more suitable for use in large production applications. It's funny, in a way, because both languages are so MUCH more dynamic than most others, that in the end the key difference between them from my POV should hinge on that — that Ruby "goes to eleven" in this regard (the reference here is to "Spinal Tap", of course). In Ruby, there are no limits to my creativity — if I decide that all string comparisons must become case-insensitive, I CAN DO THAT ! Ie, I can dynamically alter the built-in string class so that a = "Hello World" b = "hello world" if a == b print "equal!\n" else print "different!\n" end WILL print "equal". In python, there is NO way I can do that. For the purposes of metaprogramming, implementing experimental frameworks, and the like, this amazing dynamic ability of Ruby is extremely appealing. BUT — if we're talking about large applications, developed by many people and maintained by even more, including all kinds of libraries from diverse sources, and needing to go into production in client sites… well, I don't WANT a language that is QUITE so dynamic, thank you very much. I loathe the very idea of some library unwittingly breaking other unrelated ones that rely on those strings being different — that's the kind of deep and deeply hidden "channel", between pieces of code that LOOK separate and SHOULD BE separate, that spells death in large-scale programming. By letting any module affect the behavior of any other "covertly", the ability to mutate the semantics of built-in types is just a BAD idea for production application programming, just as it's cool for tinkering.

If I had to use Ruby for such a large application, I would try to rely on coding-style restrictions, lots of tests (to be rerun whenever ANYTHING changes — even what should be totally unrelated…), and the like, to prohibit use of this language feature. But NOT having the feature in the first place is even better, in my opinion — just as Python itself would be an even better language for application programming if a certain number of built-ins could be "nailed down", so I KNEW that, eg, len("ciao") is 4 (rather than having to worry subliminally about whether somebody's changed the binding of name 'len' in the builtins module…). I do hope that eventually Python does "nail down" its built-ins.

But the problem's minor, since rebinding built-ins is quite a deprecated as well as a rare practice in Python. In Ruby, it strikes me as major — just like the too powerful macro facilities of other languages (such as, say, Dylan) present similar risks in my own opinion (I do hope that Python never gets such a powerful macro system, no matter the allure of "letting people define their own domain-specific little languages embedded in the language itself" — it would, IMHO, impair Python's wonderful usefulness for application programming, by presenting an "attractive nuisance" to the would-be tinkerer who lurks in every programmer's heart…).

亚历克斯

Some others from:

http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-python/

(If I have misintrepreted anything or any of these have changed on the Ruby side since that page was updated, someone feel free to edit…)

Strings are mutable in Ruby, not in Python (where new strings are created by "changes").

Ruby has some enforced case conventions, Python does not.

Python has both lists and tuples (immutable lists). Ruby has arrays corresponding to Python lists, but no immutable variant of them.

In Python, you can directly access object attributes. In Ruby, it's always via methods.

In Ruby, parentheses for method calls are usually optional, but not in Python.

Ruby has public, private, and protected to enforce access, instead of Python's convention of using underscores and name mangling.

Python has multiple inheritance. Ruby has "mixins."

And another very relevant link:

http://c2.com/cgi/wiki?PythonVsRuby

Which, in particular, links to another good one by Alex Martelli , who's been also posting a lot of great stuff here on SO:

http://groups.google.com/group/comp.lang.python/msg/028422d707512283

I'm unsure of this, so I add it as an answer first.

Python treats unbound methods as functions

That means you can call a method either like theobject.themethod() or by TheClass.themethod(anobject) .

Edit: Although the difference between methods and functions is small in Python, and non-existant in Python 3, it also doesn't exist in Ruby, simply because Ruby doesn't have functions. When you define functions, you are actually defining methods on Object.

But you still can't take the method of one class and call it as a function, you would have to rebind it to the object you want to call on, which is much more obstuse.

I would like to mention Python descriptor API that allows one customize object-to-attribute "communication". It is also noteworthy that, in Python, one is free to implement an alternative protocol via overriding the default given through the default implementation of the __getattribute__ method. Let me give more details about the aforementioned. Descriptors are regular classes with __get__ , __set__ and/or __delete__ methods. When interpreter encounters something like anObj.anAttr , the following is performed:

  • __getattribute__ method of anObj is invoked
  • __getattribute__ retrieves anAttr object from the class dict
  • it checks whether abAttr object has __get__ , __set__ or __delete__ callable objects
  • the context (ie, caller object or class, and value, instead of the latter, if we have setter) is passed to the callable object
  • the result is returned.

As was mentioned, this is the default behavior. One is free to change the protocol by re-implementing __getattribute__ .

This technique is lot more powerful than decorators.

Ruby has builtin continuation support using callcc .

Hence you can implement cool things like the amb-operator

At this stage, Python still has better unicode support

Python has docstrings and ruby doesn't… Or if it doesn't, they are not accessible as easily as in python.

PS。 If im wrong, pretty please, leave an example? I have a workaround that i could monkeypatch into classes quite easily but i'd like to have docstring kinda of a feature in "native way".

Ruby has a line by line loop over input files (the '-n' flag) from the commandline so it can be used like AWK. This Ruby one-liner:

 ruby -ne 'END {puts $.}' 

will count lines like the AWK one-liner:

 awk 'END{print NR}' 

Ruby gets feature this through Perl, which took it from AWK as a way of getting sysadmins on board with Perl without having to change the way they do things.

Ruby has sigils and twigils, Python doesn't.

Edit : And one very important thing that I forgot (after all, the previous was just to flame a little bit :-p):

Python has a JIT compiler ( Psyco ), a sightly lower level language for writing faster code ( Pyrex ) and the ability to add inline C++ code ( Weave ).

My python's rusty, so some of these may be in python and i just don't remember/never learned in the first place, but here are the first few that I thought of:

空白

Ruby handles whitespace completely different. For starters, you don't need to indent anything (which means it doesn't matter if you use 4 spaces or 1 tab). It also does smart line continuation, so the following is valid:

 def foo(bar, cow) 

Basically, if you end with an operator, it figures out what is going on.

Mixins

Ruby has mixins which can extend instances instead of full classes:

 module Humor def tickle "hee, hee!" end end a = "Grouchy" a.extend Humor a.tickle » "hee, hee!" 

Enums

I'm not sure if this is the same as generators, but as of Ruby 1.9 ruby as enums, so

 >> enum = (1..4).to_enum => #<Enumerator:0x1344a8> 

Reference: http://blog.nuclearsquid.com/writings/ruby-1-9-what-s-new-what-s-changed

"Keyword Arguments"

Both of the items listed there are supported in Ruby, although you can't skip default values like that. You can either go in order

 def foo(a, b=2, c=3) puts "#{a}, #{b}, #{c}" end foo(1,3) >> 1, 3, 3 foo(1,c=5) >> 1, 5, 3 c >> 5 

Note that c=5 actually assigns the variable c in the calling scope the value 5, and sets the parameter b the value 5.

or you can do it with hashes, which address the second issue

 def foo(a, others) others[:b] = 2 unless others.include?(:b) others[:c] = 3 unless others.include?(:c) puts "#{a}, #{others[:b]}, #{others[:c]}" end foo(1,:b=>3) >> 1, 3, 3 foo(1,:c=>5) >> 1, 2, 5 

Reference: The Pragmatic Progammer's Guide to Ruby

You can have code in the class definition in both Ruby and Python. However, in Ruby you have a reference to the class (self). In Python you don't have a reference to the class, as the class isn't defined yet.

一个例子:

 class Kaka puts self end 

self in this case is the class, and this code would print out "Kaka". There is no way to print out the class name or in other ways access the class from the class definition body in Python.

Syntax is not a minor thing, it has a direct impact on how we think. It also has a direct effect on the rules we create for the systems we use. As an example we have the order of operations because of the way we write mathematical equations or sentences. The standard notation for mathematics allows people to read it more than one way and arrive at different answers given the same equation. If we had used prefix or postfix notation we would have created rules to distinguish what the numbers to be manipulated were rather than only having rules for the order in which to compute values.

The standard notation makes it plain what numbers we are talking about while making the order in which to compute them ambiguous. Prefix and postfix notation make the order in which to compute plain while making the numbers ambiguous. Python would already have multiline lambdas if it were not for the difficulties caused by the syntactic whitespace. (Proposals do exist for pulling this kind of thing off without necessarily adding explicit block delimiters.)

I find it easier to write conditions where I want something to occur if a condition is false much easier to write with the unless statement in Ruby than the semantically equivalent "if-not" construction in Ruby or other languages for example. If most of the languages that people are using today are equal in power, how can the syntax of each language be considered a trivial thing? After specific features like blocks and inheritance mechanisms etc. syntax is the most important part of a language,hardly a superficial thing.

What is superficial are the aesthetic qualities of beauty that we ascribe to syntax. Aesthetics have nothing to do with how our cognition works, syntax does.

Surprised to see nothing mentioned of ruby's "method missing" mechanism. I'd give examples of the find_by_… methods in Rails, as an example of the power of that language feature. My guess is that something similar could be implemented in Python, but to my knowledge it isn't there natively.

Another difference in lambdas between Python and Ruby is demonstrated by Paul Graham's Accumulator Generator problem. Reprinted here:

Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i. Note: (a) that's number, not integer, (b) that's incremented by, not plus.

In Ruby, you can do this:

 def foo(n) lambda {|i| n += i } end 

In Python, you'd create an object to hold the state of n:

 class foo(object): def __init__(self, n): self.n = n def __call__(self, i): self.n += i return self.n 

Some folks might prefer the explicit Python approach as being clearer conceptually, even if it's a bit more verbose. You store state like you do for anything else. You just need to wrap your head around the idea of callable objects. But regardless of which approach one prefers aesthetically, it does show one respect in which Ruby lambdas are more powerful constructs than Python's.

python has named optional arguments

 def func(a, b=2, c=3): print a, b, c >>> func(1) 1 2 3 >>> func(1, c=4) 1 2 4 

AFAIK Ruby has only positioned arguments because b=2 in the function declaration is an affectation that always append.

Ruby has embedded documentation:

  =begin You could use rdoc to generate man pages from this documentation =end 

In Ruby, when you import a file with require, all the things defined in that file will end up in your global namespace.

With Cargo you can " require libraries without cluttering your namespace ".

 # foo-1.0.0.rb class Foo VERSION = "1.0.0" end # foo-2.0.0.rb class Foo VERSION = "2.0.0" end 
>> Foo1 = import("foo-1.0.0")
>> Foo2 = import("foo-2.0.0")
>> Foo1::VERSION
=> "1.0.0"
>> Foo2::VERSION
=> "2.0.0"