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

已锁定。这个问题及其答案被锁定,因为这个问题离题,但具有历史意义。它目前不接受新的答案或互动。

有很多关于Python和Ruby的讨论,我都觉得它们完全没有帮助,因为它们都改变了为什么功能X在语言Y中很糟糕,或者说语言Y没有X,尽管事实上确实有。我也知道为什么我更喜欢Python,但这也是主观的,对任何人的选择都没有帮助,因为他们在开发方面可能没有我的品味

因此,客观地列出这些差异是很有意思的。所以没有“Python的lambdas很烂”。相反,解释Ruby的lambdas可以做什么,Python不能做什么。没有主观性。示例代码很好

请不要在一个答案上有几个不同。把你知道正确的投赞成票,把你知道不正确(或主观)的投反对票。此外,语法上的差异也不有趣。我们知道Python对缩进的处理方式与Ruby对括号和结尾的处理方式相同,在Python中,@被称为self

更新:这现在是一个社区wiki,因此我们可以在这里添加重大差异

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

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

例如:

卡卡级
把自己
终止

在本例中,self是类,此代码将打印出“Kaka”。无法打印出类名,也无法通过其他方式从Python中的类定义体(方法定义之外)访问该类

Ruby中的所有类都是可变的

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

类字符串
def以?(其他)开头
头部=自身[0,其他长度]
头==其他
终止
终止

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

def以(s,前缀)开头:
返回s[:len(前缀)]==前缀

您可以在任何序列(不仅仅是字符串)上使用它。为了使用它,您应该显式地导入它,例如,从某个模块导入,以开始

Ruby具有类似Perl的脚本特性

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

Ruby具有一流的连续性

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

Ruby有块

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

红宝石:

amethod{124;这里|
多行=行+行+代码
去(这里)
}

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

使用amethod()如下:#`amethod()是一个上下文管理器
多行=行+行+代码
去(这里)

对于这里的amethod():#`amethod()`是一个iterable
多行=行+行+代码
去(这里)

def函数(此处):
多行=行+行+代码
去(这里)
amethod(function)#`function`是一个回调函数

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

红宝石:

定义方法
收益率5
终止
do | foo方法|
放福
终止

Python:

def themethod():
收益率5
对于方法()中的foo:
印刷食品

虽然原则不同,但结果却惊人地相似

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

myList.map(&:description)。拒绝(&:empty?)。加入(“\n”)

Python:

descriptions=(mylist中f的f.description())
“\n”。加入(筛选器(len,说明))

Python有内置的生成器(如上所述,它们与Ruby块一样使用)

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

docs.python.org有以下生成器示例:

def倒档(数据):
对于范围内的索引(len(data)-1,-1,-1):
产量数据[指数]

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

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

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

在Python中,文件是一个模块,您可以使用模块导入*中的导入其包含的名称,从而污染名称空间。但是,您也可以使用从Module import aname(模块导入名称)导入选定的名称,另一个,或者只需导入模块,然后使用模块.aname访问名称。如果您想在名称空间中增加级别,您可以使用包,这些包是包含模块的目录和一个\uuuuu init\uuuuuu.py文件

Python有docstring

docstring是附加到模块、函数和方法的字符串,可以
在运行时内省。这有助于创建诸如help命令和
自动记录

def Frobnite(条形):
“Frobnite拿着一根棒子,把它吐出来
>>>杆=杆()
>>>钢筋已冻结()
错误的
>gt;gt;泡沫酸盐(巴)
>>>钢筋已冻结()
符合事实的
"""

Ruby的等价物类似于javadocs,位于方法上方而不是方法内部。可以在运行时使用1.9的方法#source#u location示例use从文件中检索它们

Python具有多重继承

Ruby不是(“故意”——查看Ruby的网站,在这里查看它是如何在Ruby中实现的)。它确实将模块概念作为一种抽象类重用

Python具有列表/目录理解

Python:

res=[x*x代表范围(1,10)内的x]

红宝石:

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

Python:

&gt&燃气轮机&燃气轮机;(x*x表示范围(10)内的x)
<生成器对象<genexpr>在0xb7c1ccd4处>
&燃气轮机&燃气轮机&燃气轮机;名单
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

红宝石:

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

Python2.7+

&gt&燃气轮机&燃气轮机;{1:2,3:4}.items()中的{x:str(y*y)表示x,y
{1: '4', 3: '16'}

红宝石:

&gt&燃气轮机;散列[{1=>2,3=>4}.映射{| x,y |[x,(y*y).to_s]}]
=>{1=>“4”,3=>“16”}

Python有装饰器

在Ruby中也可以创建类似于decorator的东西,也可以说它们不像Python中那样必要

语法差异

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

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

例如,数组上的每个方法的简单定义可能类似于:

类数组
定义每个
因为我自己
屈服(i)#如果一个区块已通过,控制权将在此处通过。
终止
终止
终止

然后您可以这样调用它:

#在每个元素中添加五个。
[1,2,3,4],每一个{e |放置e+5}
&燃气轮机;[6, 7, 8, 9]

Python有匿名函数/closures/lambdas,但它没有很多块,因为它缺少一些有用的语法糖。然而,至少有一种方法可以以特别的方式获得它。例如,请参见此处的

发表评论