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

What does Ruby have that Python doesn't, and vice versa?

关于python和ruby的讨论很多,我都觉得它们完全没有帮助,因为它们都改变了为什么特性x会吸收语言y,或者声称语言y没有x,尽管事实上是这样。我也知道我为什么喜欢Python,但这也是主观的,对任何人都没有帮助,因为他们在开发上可能不像我一样有品味。

因此,客观地列出这些差异是很有趣的。所以没有"Python的羊羔吮吸"。相反,解释一下Ruby的lambdas可以做什么,而python不能。没有主观性。示例代码很好!

请不要在一个答案上有几个不同。把你知道是正确的投票给他们,把那些你知道是错误的投票给他们(或是主观的)。另外,语法上的差异也不有趣。我们知道python使用缩进的方式和ruby使用方括号和端点的方式相同,在python中,@被称为self。

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

Ruby在类体中有一个类引用

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

一个例子:

1
2
3
class Kaka
  puts self
end

在这种情况下,self是类,这个代码将打印出"kaka"。无法打印出类名,也无法以其他方式从Python中的类定义体(方法定义外部)访问类。

所有类在Ruby中都是可变的

这允许您开发对核心类的扩展。下面是一个Rails扩展的示例:

1
2
3
4
5
6
class String
  def starts_with?(other)
    head = self[0, other.length]
    head == other
  end
end

python(假设没有''.startswith方法):

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

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

Ruby具有类似Perl的脚本功能

Ruby具有一流的regexps、$变量、awk/perl逐行输入循环和其他特性,这些特性使它更适合于编写小的shell脚本,这些脚本可以剪切文本文件或充当其他程序的粘合代码。

Ruby有一流的延续

感谢callcc声明。在Python中,您可以通过各种技术创建连续性,但是语言中没有内置的支持。

红宝石有积木

使用"do"语句,您可以在ruby中创建多行匿名函数,该函数将作为参数传入do前面的方法中,并从中调用。在Python中,您可以通过传递方法或使用生成器来实现这一点。

红宝石:

1
2
3
4
amethod { |here|
    many=lines+of+code
    goes(here)
}

python(ruby块对应于python中的不同构造):

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

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

1
2
3
4
5
def function(here):
    many=lines+of+code
    goes(here)

amethod(function)     # `function` is a callback

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

红宝石:

1
2
3
4
5
6
7
def themethod
    yield 5
end

themethod do |foo|
    puts foo
end

Python:

1
2
3
4
5
def themethod():
    yield 5

for foo in themethod():
    print foo

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

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

1
2
myList.map(&:description).reject(&:empty?).join("
"
)

Python:

1
2
3
descriptions = (f.description() for f in mylist)
"
"
.join(filter(len, descriptions))

python有内置的生成器(与上面提到的Ruby块类似)

Python支持该语言中的生成器。在Ruby1.8中,可以使用生成器模块,该模块使用continuations从块创建生成器。或者,您可以使用块/proc/lambda!此外,在Ruby1.9中,光纤可以用作生成器,枚举器类是内置的生成器4

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

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

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

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

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

在python中,文件是一个模块,您可以使用from themodule import *导入其包含的名称,从而在需要时污染名称空间。但您也可以使用from themodule import aname, another导入刚选定的名称,或者只需使用import themodule即可访问这些名称。如果您想要在您的名称空间中有更多的级别,您可以有包,这些包是带有模块的目录和一个__init__.py文件。

python有docstrings

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

1
2
3
4
5
6
7
8
9
10
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的方法从文件中检索源位置示例使用

python有多个继承

Ruby没有("故意"--看Ruby的网站,看这里


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

例如,在Array上对each方法的简单定义可能是:

1
2
3
4
5
6
7
class Array
  def each
    for i in self  
      yield(i)     # If a block has been passed, control will be passed here.
    end  
  end  
end

然后您可以这样调用它:

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

python有匿名的函数/闭包/lambda,但是它没有太多的块,因为它缺少一些有用的语法结构。然而,至少有一种方法可以让它成为一种特殊的方式。例如,请参见此处。


Python示例

函数是Python中的第一类变量。您可以声明一个函数,将其作为一个对象传递,并覆盖它:

1
2
3
4
5
6
def func(): print"hello"
def another_func(f): f()
another_func(func)

def func2(): print"goodbye"
func = func2

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

当然,在Ruby中有很多方法可以做到这些,但它们不是一流的操作。例如,您可以用proc.new包装一个函数,将它当作变量来处理——但是它不再是一个函数;它是一个带有"call"方法的对象。

Ruby的函数不是一流的对象

Ruby函数不是一流的对象。函数必须包装在一个对象中才能传递;结果对象不能被视为函数。不能以第一类方式分配函数;相反,必须调用其容器对象中的函数来修改它们。

1
2
3
4
5
6
7
8
9
10
11
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!"


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

我喜欢Python的语法。但是,您必须比语法更深入地挖掘才能找到Ruby的真正美。红宝石的一致性有着天籁般的美。虽然没有一个简单的例子可以完全解释这一点,但我将尝试在这里提出一个例子来解释我的意思。

反转此字符串中的单词:

1
sentence ="backwards is sentence This"

当你考虑如何做的时候,你会做以下的事情:

  • 把句子分成单词
  • 把字倒过来
  • 将单词重新连接成字符串
  • 在Ruby中,您可以这样做:

    1
    sentence.split.reverse.join ' '

    正如您所想,在相同的序列中,一个方法调用一个接一个。

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

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

    不难理解,但它的流程并不完全相同。主语(句子)被埋葬在中间。操作是函数和对象方法的混合。这是一个不起眼的例子,但是当你真正使用和理解Ruby时,你会发现很多不同的例子,尤其是在不起眼的任务上。


    Python有一种"我们都是成年人"的心态。因此,您会发现Ruby有常量之类的东西,而Python没有(尽管Ruby的常量只会发出警告)。python的思维方式是,如果要使某个变量保持不变,则应将变量名全部大写,而不是更改它。

    例如,Ruby:

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

    Python:

    1
    2
    3
    4
    >>> PI = 3.14
    >>> PI += 1
    >>> PI
    4.1400000000000006


    您只能从Python中的模块中导入特定的函数。在Ruby中,导入整个方法列表。你可以在Ruby中"使"它们不变形,但这不是全部。

    编辑:

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

    1
    2
    3
    4
    5
    6
    7
    module Whatever
      def method1
      end

      def method2
      end
    end

    如果将其包含在代码中:

    1
    include Whatever

    您将看到method1和method2都已添加到您的名称空间中。不能只导入方法1。要么两者都导入,要么根本不导入。在python中,您只能导入您选择的方法。如果它有一个名称,可能会被称为选择性导入?


    从Ruby的网站:

    相似之处和python一样,在ruby中,…

    • There’s an interactive prompt (called irb).
    • You can read docs on the command line (with the ri command instead of pydoc).
    • There are no special line terminators (except the usual newline).
    • String literals can span multiple lines like Python’s triple-quoted strings.
    • Brackets are for lists, and braces are for dicts (which, in Ruby, are called"hashes").
    • Arrays work the same (adding them makes one long array, but composing them like this a3 = [ a1, a2 ] gives you an array of arrays).
    • Objects are strongly and dynamically typed.
    • Everything is an object, and variables are just references to objects.
    • Although the keywords are a bit different, exceptions work about the same.
    • You’ve got embedded doc tools (Ruby’s is called rdoc).

    差异与python不同,在ruby中,…

    • Strings are mutable.
    • You can make constants (variables whose value you don’t intend to change).
    • There are some enforced case-conventions (ex. class names start with a capital letter, variables start with a lowercase letter).
    • There’s only one kind of list container (an Array), and it’s mutable.
    • Double-quoted strings allow escape sequences (like \t) and a special"expression substitution" syntax (which allows you to insert the results of Ruby expressions directly into other strings without having to"add" +"strings" +"together"). Single-quoted strings are like Python’s r"raw strings".
    • There are no"new style" and"old style" classes. Just one kind.
    • You never directly access attributes. With Ruby, it’s all method calls.
    • Parentheses for method calls are usually optional.
    • There’s public, private, and protected to enforce access, instead of Python’s _voluntary_ underscore __convention__.
    • "mixin’s" are used instead of multiple inheritance.
    • You can add or modify the methods of built-in classes. Both languages let you open up and modify classes at any point, but Python prevents modification of built-ins — Ruby does not.
    • You’ve got true and false instead of True and False (and nil instead of None).
    • When tested for truth, only false and nil evaluate to a false value. Everything else is true (including 0, 0.0,"", and []).
    • It’s elsif instead of elif.
    • It’s require instead of import. Otherwise though, usage is the same.
    • The usual-style comments on the line(s) above things (instead of docstrings below them) are used for generating docs.
    • There are a number of shortcuts that, although give you more to remember, you quickly learn. They tend to make Ruby fun and very productive.


    Ruby对Python的优势在于它的脚本语言能力。在此上下文中的脚本语言意味着将用于shell脚本和常规文本操作中的"粘合代码"。

    它们大多与Perl共享。第一类内置正则表达式,$变量,有用的命令行选项,如perl(-a,-e)等。

    加上它简洁的epxressive语法,它非常适合这些任务。

    对我来说,python更像是一种动态类型的业务语言,非常容易学习,而且语法也很好。不是像红宝石那样"酷",而是整洁。对于我来说,Python比Ruby有更多的绑定用于其他lib。绑定到qt和其他gui libs,许多游戏支持库和和和。红宝石的含量少得多。虽然许多常用的绑定(例如到数据库的绑定)质量很好,但我发现在Python中,即使对于同一个库也有Ruby绑定,也可以更好地支持特定的lib。

    所以,我想说这两种语言都有它的用途,这就是定义使用哪种语言的任务。两者都很容易学习。我并排使用它们。Ruby用于脚本编写,Python用于独立应用程序。


    我不认为"ruby有x,python没有,而python有y,ruby没有"是最有用的方法。它们是非常相似的语言,有许多共同的能力。

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


    我想提出一个原始问题的变体,"Ruby有什么是Python没有的,反之亦然?"这也承认了令人失望的答案,"好吧,你能用Ruby或者Python做些什么,而这在Intercal中是做不到的?"这一点上没有,因为Python和红宝石都是坐在图灵王座上的庞大皇室成员。

    但是这个呢:

    在拥有如此美丽和良好工程的Ruby中做不到的、在Python中优雅而出色的工作是什么,反之亦然?

    这可能比单纯的特征比较有趣得多。


    无耻地复制/粘贴自:alex martelli answer on"What's better about ruby than python"thread from comp.lang.python mail list.好的。

    Aug 18 2003, 10:50 am Erik Max Francis
    wrote:

    Ok.

    "Brandon J. Van Every" wrote:

    Ok.

    What's better about Ruby than Python? I'm sure there's something.
    What is it?

    Ok.

    问鲁比人这个问题,不是比问Python?好的。< /块引用>

    可能,也可能不会,取决于目的——例如,如果一个人的目的包括"社会学"然后学习"python社区"向社区提问是可能会证明关于它的信息,而不是其他地方:—)。好的。

    就我个人而言,我很高兴跟随戴夫·托马斯的机会最后奥森的一天Ruby教程。下面是一层薄薄的句法不同之处,我发现Ruby和Python惊人的相似——如果我是最小生成树的计算在几乎所有的语言中,我敢肯定Python和鲁比会的是前两片叶子凝聚在一起进入中间节点:-)。好的。

    当然,我确实厌倦了,在鲁比在结尾处键入愚蠢的"end"每个街区(而不仅仅是不请自来——但我还是要去避免输入同样愚蠢的":"python在从每个街区开始,这几乎是一次洗礼。其他语法差异,如"@foo"与"self.foo"或更高意义在Ruby和Python中,实际上和我没什么关系。好的。

    其他人无疑是基于他们的选择编程语言就这样问题,它们产生最热的辩论——但对我来说,那只是帕金森定律的一个例子行动(关于问题与问题的实际重要性)。好的。

    编辑(2010年6月19日上午11:45):这也被称为"绘画骑自行车"(或者,简而言之,"bikeshedding")——参考文献是,再次向Northcote Parkinson报告,关于要画什么颜色的争论自行车"是典型的"关于琐碎话题的激烈辩论"。(编辑结束)。好的。

    我发现一个语法的差异Python中的重要和有利的。但其他人将毫无疑问的智囊团准时制技术是"反向"的你这需要在调用的函数参数"。在Python中,C类)你总是打电话给该函数的应用"呼叫运营商"——尾parentheses只是后的对象你的电话(在那些拖当你走在parentheses传递在电话中,如果你传递一个是空的,然后parentheses)。该叶片的仅仅提到)在运营商的任何对象,以参与的意义,只是参考在任何上下文中的对象。没有例外,特殊情况下,特设的规则,和喜欢。在红宝石(如在Pascal),呼叫功能你的一个通带参数在parentheses(通常是,但的情况是不invariably)-如果然后,在一个时间的函数implicitly功能提调用它。这可能会在许多人预期(至少,毫无疑问,他以前的那些。为研究与编程经验Pascal语言的,或与其他类似的"隐式调用,如Visual Basic),但对我,它的均值不过值得一提的一个对象的可能无论是均参考的对象。或调用的对象,这取决于该对象的类型和那些的情况下,I can’t get a参考它仅仅由一提的对象将需要使用显式的"给我参考这个,Don’t call it!"这是不必要的运营商的T另有。我感觉到这种影响的"第一classness"功能(或的方法,或其他可调用的对象)的可能性,interchanging平稳的对象。因此,我,这是一个特定的语法差异严重的,但对黑宝石我明白为什么其他人做的事此外,虽然我可以hardly与他们的vehemently disagree更多:-)。

    下面的语法,我们进入的一些重要的差异在小学语义的-例如,字符串中的红宝石是可变对象(类)C + +),他们是在Python中不在Java(或可变),我相信C #)。再次,人谁?主要是由他们再已这可能是一个熟悉的智囊团)是红宝石(除非他们再熟悉当然,Java或C #,:-)。我,我想一个良好的字符串是不变的我不算是surprised Java我想是独立的,reinventedPython中的想法),这已经虽然我不介意有"可变字符串缓冲区类型的阱一个具有更好的(和ideally(一)比不使用自己的"Java的字符串缓冲区)和"I Don’t;给本判断--因为语学习Java之前,除了在功能性编程语言所有的数据都是不变的,我知道所有的语言,有可变的字符串然而,当我第一次看到--《不变的字符串(这一想法在Java在过去,我知道,好的python)它立即使我的优秀。很好的拟合语义的更高的水平(参考)两喷嘴对置(编程语言)这是最佳的拟合值与语义与更接近机器语言farther从应用程序,如(C)与字符串的第一级。内置的日期(和漂亮的关键)型。

    也有一些优点,在红宝石基本语义的-例如,在去除与Python"列表exceedingly元组"的文字区别。但大部分的分数我保持它的简单加和,大在distinctions和微妙的,聪明的著名的红宝石是负)对(例如,具有封闭式和半开放式。区间,这与notations ..b和任何人想在那...b [索赔这是明显的,这是它吗?-)],是一-我真傻,当然!)同样,。。。。。。。有很多人谁认为类似的,但不同的人在subtly语言的核心功能,而不是当然,不减,将计数这些"其他方式从周围的知识"其中:I count)。

    不要被这些比较误导认为这两种语言是很不一样,当心你。不是,但如果我被要求比较"Capelli d'Angelo"到"Spaghettini",在指出这两个各种意大利面任何人都无法辨别在任何盘子里都可以互换我想准备一下不可避免地要进入显微镜检查长度和直径难以察觉不同,股的末端一种情况下是锥形的,而不是其他等等——试着解释为什么我个人更愿意卡佩利·德安吉洛作为意大利面有点肉汤,不过更喜欢意大利面意大利面用合适的酱汁煮这么久薄面食形式(橄榄油,切碎)大蒜、剁碎的红辣椒和细碎的例如,地面凤尾鱼——但如果你把大蒜和辣椒切成片了而不是把它们弄碎,那么你应该选择发声器的主体意大利面而不是稀薄的斯帕格蒂尼的消亡最好放弃阿乔维人换上一些新鲜的泉水巴兹尔[甚至--我是个异教徒…!——轻薄荷…]叶——非常上菜前的最后一刻)。哦,对不起,这表明我出国旅行,没有吃意大利面我想有一段时间。但类比还是不错的!-)好的。

    所以,回到python和ruby,我们来给两个大人物语言恰当——离开图书馆和其他重要的辅助工具,如工具和环境,如何嵌入/扩展语言等等,暂时不需要了--它们不适用于每种语言的所有实现不管怎样,比如Jython和经典的python作为python语言!):好的。

  • Ruby的迭代器和代码块vs python的迭代器和生成器;好的。

  • 鲁比的全面、无拘无束的"活力",包括要"重新打开"任何现有类,包括所有内置的,以及在运行时更改其行为--vsPython的巨大但有界充满活力,永不改变现有内置的行为类及其实例。好的。

  • 就我个人而言,我认为差异如此之深,我可以很容易看出人们也讨厌接近并回荡另一个,但是在我个人的天平上减号大约等于偶数);和2 A关键问题——使Ruby更适合"修补",但Python同样更适合用于大型生产应用。在某种程度上,这很有趣,因为两者都是语言更具活力比其他大多数人,最后它们与我的POV应该依靠那个--那个红宝石在这方面,"转到11"(即这里提到的是"脊柱拍打",属于课程)。在Ruby中,没有限制为了我的创造力——如果我决定的话所有字符串比较必须不区分大小写,我能做到!也就是说,我可以动态地改变内置的字符串类,以便A="你好,世界"B="你好,世界"如果a==B打印"平等"!"N"其他的打印"不同!"N"END将打印"等于"。在Python中,我无法做到这一点。为了元编程的目的,实施实验框架,像这样,这个惊人的动态红宝石的能力非常强吸引人的。但是——如果我们在谈话关于大型应用程序,由很多人甚至被更多,包括各种图书馆来自不同的来源,需要在客户端站点投入生产…好吧,我不想要那种语言很有活力,非常感谢。我讨厌图书馆的想法无意中打破了其他无关的那些依靠这些弦的不同——那是那种深沉的以及深藏的"通道",介于看起来分开的代码片段应该是分开的大规模编程中的D-E-A-T-H。通过让任何模块影响任何其他"秘密"的行为,能够改变内置类型只是一个坏主意生产应用程序设计,就像修修补补一样酷。好的。

    如果我不得不用红宝石做这么大的申请,我会尽量依靠编码样式限制,很多测试(任何时候都要重新运行改变——即使是完全应该改变的不相关的……)等等禁止使用此语言功能。但在首先,在我的意见——就像python本身一样成为更好的语言应用程序编程如果可以"确定"内置的数量向下",所以我知道,例如,Len("Ciao")是4岁(而不是下意识地担心有人改了名字的装订内置模块中的"len"…)。我真的希望最后Python能做到"钉住"它的内置部件。好的。

    但问题很小,因为重新绑定内置组件是相当大的弃用以及罕见的做法在Python中。在红宝石中,它给我的印象是少校——就像太强大了其他语言的宏观设施(比如说,迪伦)表现得相似我个人认为的风险(我希望那条Python永远不会变得如此强大宏观体系,无论"让人们定义自己的特定于域的小语言嵌入到语言本身中--it会,imho,损害python的精彩适用性编程,通过演示"有吸引力的麻烦"的未来潜伏在每一个程序员的心…)。好的。

    亚历克斯好的。< /块引用>好啊。


    python有一个用于列表理解和生成器的显式内置语法,而在Ruby中,您将使用映射和代码块。

    比较

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

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


    "以大写字母开头的变量变为常量,无法修改"

    错了。他们可以。

    只有这样你才会得到警告。


    在基础设施方面,更多的是:

    • Python与Ruby(如Boosix.Python、SIP和Py++)相比,与Ruby有更好的集成,其中的选项似乎可以直接写入Ruby解释器API(当然也可以使用Python来编写,但是在这两种情况下,这样做都是低级别、繁琐和容易出错),或者使用SWIG(尽管它是有效的和明确的)。如果你想支持多种语言,LY很好,如果你特别想绑定C++的话,它不如Booost。Python或SIP那么好。

    • python有许多Web应用程序环境(django、pylons/turbogears、web.py,可能至少还有六个),而ruby(实际上)有一个:rails。(其他RubyWeb框架确实存在,但似乎很难对Rails有很大的吸引力)。这方面是好是坏?很难说,而且可能很主观;我可以很容易地想象出这样的论点:Python的情况更好,Ruby的情况更好。

    • 在文化上,python和ruby社区似乎有些不同,但我只能暗示这一点,因为我没有那么多与ruby社区交互的经验。我补充说这一点主要是希望那些对两者都有丰富经验的人能够放大(或拒绝)这一说法。


    其他一些来自:

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

    (如果我错误地描述了自该页面更新后Ruby端的任何内容或其中任何内容发生了更改,那么有人可以自由编辑…)

    字符串在ruby中是可变的,而不是在python中(其中新字符串是由"changes"创建的)。

    Ruby有一些强制的大小写约定,而Python没有。

    python同时具有列表和元组(不可变的列表)。Ruby有对应于Python列表的数组,但没有它们的不可变变体。

    在Python中,可以直接访问对象属性。在Ruby中,总是通过方法。

    在Ruby中,方法调用的括号通常是可选的,但在Python中不是。

    Ruby有公共的、私有的和受保护的来强制访问,而不是Python使用下划线和名称管理的约定。

    python有多个继承。鲁比有"混音"。

    还有另一个非常相关的链接:

    http://c2.com/cgi/wiki?巨嘴鸟

    特别是,它链接到了亚历克斯·马泰利的另一个好网站,他也在这里发布了很多很棒的东西,所以:

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


    我不确定,所以我先把它作为答案。

    python将未绑定的方法视为函数

    这意味着您可以调用像theobject.themethod()TheClass.themethod(anobject)这样的方法。

    编辑:虽然在Python中方法和函数之间的差异很小,而在Python3中不存在,但在Ruby中也不存在,这仅仅是因为Ruby没有函数。定义函数时,实际上是在对象上定义方法。

    但是你仍然不能将一个类的方法作为一个函数来调用它,你必须将它重新绑定到你想要调用的对象上,这更为棘手。


    我想提到允许一个自定义对象属性为"通信"的python描述符API。值得注意的是,在python中,可以通过覆盖通过默认实现__getattribute__方法给出的默认值来自由地实现替代协议。让我详细介绍一下上述内容。描述符是使用__get____set__和/或__delete__方法的常规类。当译员遇到类似于anObj.anAttr的情况时,执行以下操作:

    • 调用anObj__getattribute__方法
    • __getattribute__从类dict中检索anattr对象
    • 它检查abattr对象是否有__get____set____delete__可调用对象
    • 上下文(即调用方对象或类以及值,而不是后者,如果我们有setter的话)被传递给可调用对象。
    • 返回结果。

    如前所述,这是默认行为。一种是通过重新实现__getattribute__来自由更改协议。

    这项技术比装饰工要强大得多。


    在这个阶段,python仍然有更好的unicode支持


    Ruby使用callcc提供了内置的延续支持。

    因此,您可以实现一些很酷的东西,比如amb操作符。


    Ruby有sigils和twigils,而python没有。

    编辑:还有一件很重要的事我忘了(毕竟,前一件只是为了点燃一点火焰):-p:

    Python有一个JIT编译器(PyCo),它是一种用于编写更快代码(Pyrx)和添加内联C++代码(WAVE)的外观较低的语言。


    在Ruby和Python中,类定义中都可以有代码。但是,在Ruby中,您有一个对类(self)的引用。在Python中,您没有对类的引用,因为类尚未定义。

    一个例子:

    1
    2
    3
    class Kaka
      puts self
    end

    在这种情况下,self是类,这个代码将打印出"kaka"。无法打印出类名,也无法以其他方式从Python中的类定义体访问类。


    python有docstrings,ruby没有…或者如果没有,就不能像在Python中那样容易地访问它们。

    另外,如果我错了,漂亮的,请留下一个例子?我有一个解决方案,我可以很容易地将其MonkeyPatch移植到类中,但我希望以"本机方式"使用DocString这种功能。


    Ruby在命令行中的输入文件('-n'标志)上有一个逐行循环,因此可以像awk一样使用它。这款Ruby One衬里:

    1
    ruby -ne 'END {puts $.}'

    将计算像awk one liner这样的行:

    1
    awk 'END{print NR}'

    Ruby通过Perl获得了这个特性,它从awk获得了这个特性,作为一种让SysAdmins加入Perl的方法,而不必改变它们的工作方式。


    我的Python生锈了,所以其中一些可能是在Python身上,我只是不记得/一开始从未学过,但下面是我想到的前几个:

    空白

    Ruby处理空白的方式完全不同。对于初学者来说,您不需要缩进任何内容(这意味着如果使用4个空格或1个制表符就不重要)。它还执行智能线路延续,因此以下内容有效:

    1
    2
    def foo(bar,
            cow)

    基本上,如果你以一个接线员结束,它就会知道发生了什么。

    混合蛋白

    Ruby有mixin,可以扩展实例而不是完整类:

    1
    2
    3
    4
    5
    6
    7
    8
    module Humor
      def tickle
       "hee, hee!"
      end
    end
    a ="Grouchy"
    a.extend Humor
    a.tickle    ?  "hee, hee!"

    枚举类型

    我不确定这是否与生成器相同,但是对于Ruby1.9Ruby,它与Enums相同,所以

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

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

    "关键字参数"

    Ruby支持列出的这两个项目,但不能跳过这样的默认值。你要么按顺序走

    1
    2
    3
    4
    5
    6
    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

    注意,C=5实际上在调用范围中为变量C分配了值5,并将参数B设置为值5。

    或者你也可以用哈希来解决第二个问题

    1
    2
    3
    4
    5
    6
    7
    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

    参考文献:Ruby实用程序指南


    语法不是一件小事,它直接影响到我们的思维方式。它还直接影响我们为使用的系统创建的规则。作为一个例子,我们有操作的顺序,因为我们写数学方程或句子的方式。数学的标准符号可以让人们不止一种方式阅读它,并在同一个方程式下得出不同的答案。如果我们使用前缀或后缀表示法,我们将创建规则来区分要操作的数字,而不仅仅是计算值的顺序规则。

    标准的表示法让我们清楚地知道我们谈论的数字是什么,同时也让计算它们的顺序变得模糊不清。前缀和后缀表示法使计算的顺序变得不明确。如果不是因为语法空白造成的困难,Python已经有了多行lambda。(确实存在这样的建议,即不必添加明确的块分隔符就可以完成这类工作。)

    我发现,如果条件为假,那么编写条件就更容易,如果条件为假,那么使用ruby中的除非语句编写条件就比Ruby或其他语言中语义上等价的"if not"结构容易得多。如果人们现在使用的大多数语言在权力上是平等的,那么每种语言的语法又如何被认为是微不足道的呢?句法是语言中最重要的部分,而不是表面的东西。

    表面上看,美的美学特质是我们归因于句法的。美学与我们的认知方式无关,句法是如此。


    看到Ruby的"方法缺失"机制没有提到,我很惊讶。我会举一些例子来说明这个发现。Rails中的方法,作为该语言功能强大的示例。我的猜测是类似的东西可以在Python中实现,但据我所知,它并不是本地实现的。


    python和ruby在lambda中的另一个区别是由paul graham的accumulator generator问题证明的。此处转载:

    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.

    在Ruby中,您可以这样做:

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

    在python中,您将创建一个对象来保存n的状态:

    1
    2
    3
    4
    5
    6
    class foo(object):
        def __init__(self, n):
            self.n = n
        def __call__(self, i):
            self.n += i
            return self.n

    有些人可能更喜欢显式的Python方法,因为它在概念上更清晰,即使它有点冗长。你像对待其他事情一样存储状态。你只需要把你的头绕在可调用对象的概念上。但不管人们喜欢哪种美学方法,它确实显示了一个方面,即RubyLambda比Python更强大。


    python已命名可选参数

    1
    2
    3
    4
    5
    6
    7
    def func(a, b=2, c=3):
        print a, b, c

    >>> func(1)
    1 2 3
    >>> func(1, c=4)
    1 2 4

    AfaikRuby只有定位参数,因为函数声明中的b=2是一个始终附加的矫揉造作。


    Ruby有嵌入式文档:

    1
    2
    3
    4
    5
     =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.

    使用cargo,您可以"要求库而不使名称空间混乱"。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # foo-1.0.0.rb
    class Foo
      VERSION ="1.0.0"
    end

    # foo-2.0.0.rb
    class Foo
      VERSION ="2.0.0"
    end
    1
    2
    3
    4
    5
    6
    >> Foo1 = import("foo-1.0.0")
    >> Foo2 = import("foo-2.0.0")
    >> Foo1::VERSION
    =>"1.0.0"
    >> Foo2::VERSION
    =>"2.0.0"


    http://c2.com/cgi/wiki?巨嘴鸟http://c2.com/cgi/wiki?从pythontoruby切换http://c2.com/cgi/wiki?从rubytopython切换http://c2.com/cgi/wiki?使用ythondontnedRubyhttp://c2.com/cgi/wiki?使用GrubyDontnedpython


    我喜欢Ruby和Python方法调用操作方式的基本区别。

    Ruby方法是通过"消息传递"的形式调用的,不需要显式地成为第一类函数(有一些方法可以将方法提升为"适当的"函数对象)--在这方面,Ruby与Smalltalk类似。

    python的工作方式更像是javascript(甚至Perl),其中方法是直接调用的函数(也有存储的上下文信息,但是…)

    虽然这看起来像是一个"次要"的细节,但实际上它只是Ruby和Python设计有多不同的表面。(另一方面,它们也完全相同:—)

    一个实际的区别是Ruby中method_missing的概念(无论好坏,它似乎在一些流行的框架中使用)。在Python中,可以(至少部分地)使用uugetattr_uu/uugetattribute_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu


    有人给出的嵌套词法范围示例有几个好处。

  • "更安全"的全球
  • 这是一种将DSL嵌入到程序中的方法。
  • 我认为这是两种语言差异的一个很好的例子。红宝石只是更灵活。python可以很灵活,但是你经常需要做一些极端的扭曲来达到目的,这使得它不值得麻烦。

    很抱歉,没有在原始答案下发布,我想我没有权限这样做。


    关于Ruby的块的更多信息

    有人建议Ruby的块可以被Python的上下文管理器"替换"。事实上,块允许的内容比Python的上下文管理器要多。

    块的接收方法可以在某个对象的上下文中执行该块,从而允许该块调用其他无法实现的方法。Python的生成器也不能做到这一点。

    一个简单的例子可能有助于:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class Proxy
       attr_accesor :target

       def method &block
          # Ruby 1.9 or in Rails 2.3
          target.instance_exec &block  
       end
    end

    class C
       private
       def hello
         puts"hello"
       end
    end

    p = Proxy.new
    c = C.new
    p.target = c
    p.method { hello }

    在本例中,块{ hello }中的方法调用在目标对象c的上下文中具有真正意义。

    此示例仅用于说明目的。在另一个对象的上下文中使用这种执行的实际工作代码并不少见。例如,监控工具godm使用它。


    我很惊讶没有人提到单例方法。

    1
    2
    3
    4
    5
    a=[]
    b=[]
    def b.some_method do ... end
    b.some_method #fine
    a.some_method #raises exception

    它提供了对开放类概念的粒度控制。您还可以使用本征类将模块混合到特定对象中,而不是给定类的所有对象中。

    1
    2
    3
    4
    o=Object.new
    class << o
      include SomeModule
    end

    python也没有switch语句,如果不使用丑陋的hacks,这会降低代码的可读性。

    Ruby没有语句,只有表达式。这增加了很大的灵活性。

    您可以获得对任何方法的引用并传递它。

    1
    2
    a=[]
    m=a.method :map #m is now referencing an instance of Method and can be passed like any other reference to an object and is invoked with the call method and an optional block

    简单的嵌套词法范围,提供受控的全局变量。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    lambda {
       global=nil
       def Kernel.some_global= val
          global||=val
       end

      def Kernel.some_global
         global
      end
    }.call

    一旦调用了lambda,则global就超出了作用域,但是您可以设置它(在本例中只有一次),然后在程序的任何地方访问它。希望它的价值是明确的。

    在Ruby中创建DSL要比在Python中容易得多。在Python中创建类似rake或rspec的东西是可能的,但这将是一个多么可怕的噩梦。所以要回答您的问题,Ruby比Python更灵活。它不在Lisp的灵活性级别,但可以说是最灵活的OO语言。

    Python非常棒,但和红宝石相比,它的硬度太高了。Ruby不那么冗长,可读性更高(因为它读起来更接近自然语言),而python读起来就像英语翻译成法语一样。

    python也很烦人,因为它的社区总是与guido紧密相连,如果guido说您不需要特性x,那么社区中的每个人都会相信它并重复它。它导致了一个陈旧的社区,有点像Java社区,根本无法理解匿名函数和闭包给你买什么。python社区不像haskell社区那么烦人,但仍然如此。


    Ruby通过单一继承获得继承权

    我有没有提到Ruby有一个史诗般的开发者社区。忍者主题灵感来自面向对象的红宝石:类,混音和绝地。

    Ruby通过单一继承获得了继承权!需要使用多重继承来表示域关系是设计不当的系统的一个症状。多重继承造成的混乱不值得增加功能。

    假设你有一个叫做kick的方法:

    1
    2
    3
    def kick
      puts"kick executed."
    end

    如果踢腿在忍术和少林中都有定义呢?这里多重继承失败,这就是为什么python失败的原因:

    1
    2
    3
    4
    5
    class Mortal < Ninjutsu, Shaolin
      def initialize
        puts"mortal pwnage."
      end
    end

    在Ruby中,如果需要忍者,可以创建忍者类的实例。如果你需要一个少林高手,你可以创建一个少林类的实例。

    1
    2
    3
    4
    5
    6
    7
    ninja = Ninjutsu.new
    ninja.kick

    or

    master = Shaolin.new
    master.kick

    Ruby通过mixin获得了继承权

    忍者和少林高手可能都有相同的踢腿技术。再读一遍-两人都有相同的行为-没有别的!python会鼓励您进行一个全新的类。不要和露比在一起!在Ruby中,您只需使用mixin:

    1
    2
    3
    4
    5
    module Katas
      def kick
        puts"Temporal Whip Kick."
      end
    end

    简单地将katas模块混合到Ruby类中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    require 'Katas'

    class Moral < Ninjutsu
      include Katas

      def initialize
        puts"mortal pwnage."
      end
    end

    然后你的行为就会被分享——这就是你真正想要的。不是整个班级。这是ruby和python最大的区别——ruby继承正确!


    虽然功能在很大程度上是相同的(特别是图灵意义上),恶意语言声称Ruby是为pythonistas创建的,不能与Perlish编码风格分离。