有很多关于Python和Ruby的讨论,我都发现它们完全没有帮助,因为它们都围绕着为什么X特性在Y语言中很糟糕,或者声称Y语言没有X,尽管事实上它有。我也确切地知道为什么我更喜欢Python,但这也是主观的,对任何人的选择都没有帮助,因为他们可能与我在开发方面的品味不同。

因此,客观地列出这些差异将是有趣的。所以没有“Python的lambdas很糟糕”。相反,解释Ruby的lambda能做而Python不能做的事情。没有主体性。示例代码很好!

请不要在一个答案上有几个不同之处。然后给你认为正确的选项投票,把你认为不正确的(或主观的)选项投下。此外,语法上的差异也不有趣。我们知道Python对缩进的处理就像Ruby对括号和结束的处理一样,@在Python中被称为self。

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

Ruby在类主体中有一个类引用

在Ruby中,类主体中已经有了对类(self)的引用。在Python中,直到类构造完成之后才有对类的引用。

一个例子:

class Kaka
  puts self
end

self在本例中是类,这段代码将打印出“Kaka”。在Python中,无法打印类名或以其他方式从类定义体(在方法定义之外)访问类。

Ruby中所有的类都是可变的

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

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

你可以在任何序列上使用它(不仅仅是字符串)。为了使用它,你应该显式地导入它,例如,从some_module import starts_with。

Ruby具有类似perl的脚本功能

Ruby拥有一流的regexp、$-variables、awk/perl逐行输入循环和其他特性,这些特性使它更适合编写小型shell脚本,这些脚本可以转换文本文件或充当其他程序的粘合代码。

Ruby具有一流的延续

多亏了callcc语句。在Python中,您可以通过各种技术创建continuation,但语言中没有内置的支持。

Ruby有块

通过“do”语句,您可以在Ruby中创建一个多行匿名函数,该函数将作为参数传递到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)

Or

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

Or

def function(here):
    many=lines+of+code
    goes(here)

amethod(function)     # `function` is a callback

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

Ruby:

def themethod
    yield 5
end

themethod do |foo|
    puts foo
end

Python:

def themethod():
    yield 5

for foo in themethod():
    print foo

尽管原理不同,结果却惊人地相似。

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

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中,您可以使用generator模块,该模块使用continuation从块中创建生成器。或者,你可以使用block/proc/lambda!此外,在Ruby 1.9中,光纤可以用作生成器,并且枚举器类是一个内置生成器4

Docs.python.org有这样一个生成器示例:

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

将其与上面的块示例进行对比。

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

在Ruby中,当您使用require导入文件时,该文件中定义的所有内容都将在全局名称空间中结束。这会导致名称空间污染。解决方案就是ruby模块。但是如果使用模块创建名称空间,则必须使用该名称空间访问包含的类。

在Python中,该文件是一个模块,您可以从模块import *中导入其包含的名称,从而污染命名空间。但是你也可以从模块import aname中导入选定的名称,或者你可以简单地导入模块,然后使用module.aname访问这些名称。如果你想在你的命名空间中有更多的层,你可以有包,包是包含模块和__init__.py文件的目录。

Python有文档字符串

文档字符串是附加到模块、函数和方法的字符串 在运行时内省。这有助于创建帮助命令和 自动文档。

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具有多重继承

Ruby没有(“故意的”——请参阅Ruby的网站,了解在Ruby中是如何做到的)。它将模块概念重用为一种抽象类。

Python有列表/字典推导式

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 Python

>>> {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中也可以创建类似于装饰器的东西,也可以认为它们不像在Python中那样必要。

语法差异

Ruby需要“end”或“}”来关闭所有作用域,而Python只使用空白。Ruby中最近已经尝试允许只使用空格缩进http://github.com/michaeledgar/seamless


当前回答

Ruby有内置的使用callcc的延续支持。

因此你可以实现一些很酷的东西,比如amb-operator

其他回答

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.

标准符号使我们所讨论的数字一目了然,但计算它们的顺序却不明确。前缀和后缀表示法使计算顺序清晰明了,同时使数字模糊。如果不是语法空白造成的困难,Python已经有了多行lambda。(确实存在这样的建议,即不需要添加显式的块分隔符。)

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.

肤浅的是我们归于语法的美的审美品质。美学与我们的认知如何运作无关,但句法起作用。

在Ruby中,当你用 Require,定义的所有东西 该文件将在全局变量中结束 名称空间。

使用Cargo,你可以“在不弄乱名称空间的情况下要求库”。

# 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"

Ruby相对于Python的优势在于它的脚本语言能力。脚本语言在此上下文中的意思是用于shell脚本和一般文本操作中的“粘合代码”。

这些主要与Perl共享。一流的内置正则表达式,$-Variables,有用的命令行选项,如Perl (-a, -e)等。

再加上它简洁而富有表现力的语法,它非常适合这类任务。

对我来说,Python更像是一种动态类型的业务语言,非常容易学习,而且语法简洁。没有Ruby那么“酷”,但是很简洁。 对我来说,Python相对于Ruby的优势是对其他库的大量绑定。绑定到Qt和其他GUI库,许多游戏支持库和和。Ruby拥有的要少得多。虽然很多常用的绑定(例如数据库绑定)质量都很好,但我发现Python中对利基库的支持更好,即使同一个库中也有Ruby绑定。

所以,我想说两种语言都有它的用途,是任务定义了使用哪一种。两者都很容易学。我把它们放在一起用。Ruby用于脚本,Python用于独立应用程序。

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

在很大程度上,区别在于语言如何变得优雅和可读。以您提到的一个例子来说,两者理论上都有lambdas,但是Python程序员倾向于避免使用它们,并且使用它们构建的结构看起来不像Ruby中那样可读或惯用。所以在Python中,优秀的程序员会想要采用不同于Ruby的方法来解决问题,因为这实际上是更好的方法。

最终,所有的答案在某种程度上都是主观的,到目前为止发布的答案几乎证明了你不能以同样好的方式(如果不是相似的话)指出任何一个功能在另一种语言中是不可行的,因为这两种语言都非常简洁和富有表现力。

我喜欢Python的语法。但是,除了语法之外,您还必须深入挖掘Ruby的真正魅力。在林心如的一贯中有一种禅意般的美。虽然没有一个简单的例子可以完全解释这一点,但我会试着在这里举一个例子来解释我的意思。

颠倒这个字符串中的单词:

sentence = "backwards is sentence This"

当你考虑如何做到这一点时,你会这样做:

把这个句子分成几个单词 颠倒单词 将单词重新连接成字符串

在Ruby中,你可以这样做:

sentence.split.reverse.join ' '

正如您所想的那样,在相同的顺序中,一个方法调用另一个方法。

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

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

这并不难理解,但它并没有完全相同的流程。主语(句)被埋没在中间。操作是函数和对象方法的混合。这是一个简单的例子,但是当你真正使用和理解Ruby时,你会发现许多不同的例子,特别是在非简单的任务中。