问题:Ruby有Python没有的,反之亦然?
关于Python与Ruby的讨论很多,我都发现它们完全无济于事,因为它们都绕开了为什么功能X吸收了语言Y或声称语言Y没有X的事实,尽管实际上确实如此。我也确切地知道为什么我偏爱Python,但这也是主观的,并且不会帮助任何人选择,因为他们在开发中的品味可能不如我。
因此,客观列出差异是很有趣的。因此,没有“ Python的lambdas很烂”。相反,请解释Ruby的lambda可以做什么,而Python则不能。没有主观性。示例代码很好!
请在一个答案中没有几个差异。并投票支持您所知道的正确和不正确(或主观)的投票。同样,语法上的差异也不是很有趣。我们知道Python用缩进来做,而Ruby用括号来做,而@在Python中被称为self。
更新:这是现在的社区Wiki,因此我们可以在此处添加较大的差异。
Ruby在类主体中有一个类引用
在Ruby中,您已经在类主体中引用了该类(自身)。在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
您可以在任何序列上使用它(不仅是字符串)。为了使用它,您应该显式导入它,例如from some_module import starts_with
。
Ruby具有类似Perl的脚本功能
Ruby具有一流的正则表达式,$变量,awk / perl逐行输入循环以及其他功能,使其更适合于编写小型shell脚本,这些脚本会压缩文本文件或充当其他程序的粘合代码。
Ruby具有一流的延续性
感谢callcc声明。在Python中,您可以通过各种技术来创建延续,但是该语言没有内置支持。
红宝石有块
使用“ do”语句,您可以在Ruby中创建一个多行匿名函数,该函数将作为参数传递给do前面的方法,然后从那里调用。在Python中,您可以通过传递方法或使用生成器来实现。
红宝石:
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中将创建一个生成器。
红宝石:
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模块,该模块使用延续从一个块中创建一个generator。或者,您可以只使用block / proc / lambda!此外,在Ruby 1.9中,光纤是并且可以用作生成器,而Enumerator类是内置的生成器4
docs.python.org包含以下生成器示例:
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
名称themodule.aname
。如果要在命名空间中使用更多级别,则可以有包,包是带有模块和__init__.py
文件的目录。
Python具有文档字符串
文档字符串是附加到模块,函数和方法的字符串,可以在运行时自省。这有助于创建诸如help命令和自动文档之类的东西。
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 示例use在运行时从文件中检索它们。
Python具有多重继承
Ruby不会(“故意”-请访问Ruby的网站,在这里查看它是如何在Ruby中完成的)。它确实将模块概念作为一种抽象类重用。
Python具有列表/字典理解
Python:
res = [x*x for x in range(1, 10)]
红宝石:
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]
红宝石:
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'}
红宝石:
>> 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
回答 0
Ruby具有块的概念,它们实际上是围绕一段代码的语法糖。它们是创建闭包并将其传递给可能使用也可能不使用该块的另一种方法。稍后可以通过一条yield
语句调用一个块。
例如,对each
方法的简单定义Array
可能类似于:
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,但由于缺少一些有用的语法糖,因此它没有块。但是,至少有一种方法可以临时获得它。例如,请参阅此处。
回答 1
Python范例
函数是Python中的一类变量。您可以声明一个函数,将其作为对象传递,然后覆盖它:
def func(): print "hello"
def another_func(f): f()
another_func(func)
def func2(): print "goodbye"
func = func2
这是现代脚本语言的基本特征。JavaScript和Lua也这样做。Ruby并不以这种方式对待函数。给函数命名会调用它。
当然,有很多方法可以在Ruby中完成这些操作,但它们不是一流的操作。例如,您可以使用Proc.new包装函数以将其视为变量,但是它不再是函数;它是带有“调用”方法的对象。
Ruby的功能不是一流的对象
Ruby函数不是一流的对象。必须将函数包装在一个对象中以将它们传递给对象。结果对象不能像函数一样对待。不能以一流的方式分配功能;相反,必须调用其容器对象中的函数以对其进行修改。
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!"
回答 2
最终,所有答案都将在一定程度上是主观的,到目前为止发布的答案几乎证明,您无法以同样不错的方式(如果不是相似的方式)指向其他语言无法实现的任何功能,因为这两种语言都很简洁明了。
我喜欢Python的语法。但是,您必须比语法更深入一点,才能找到Ruby的真正魅力。Ruby的一致性具有禅宗般的美。虽然没有任何简单的示例可以完全解释这一点,但我将在此处尝试提出一个示例以解释我的意思。
反转此字符串中的单词:
sentence = "backwards is sentence This"
在考虑如何做时,请执行以下操作:
- 把句子分成单词
- 反转字
- 重新将单词重新组合成字符串
在Ruby中,您可以这样做:
sentence.split.reverse.join ' '
正如您所想的那样,以相同的顺序依次调用一个方法。
在python中,它将看起来像这样:
" ".join(reversed(sentence.split()))
这不难理解,但流程不尽相同。主题(句子)埋在中间。这些操作是功能和对象方法的混合。这是一个简单的示例,但是在真正使用和理解Ruby时,尤其是在非琐碎的任务上,人们发现了许多不同的示例。
回答 3
Python具有“我们都在这里成年”的心态。因此,您会发现Ruby具有类似常量的功能,而Python没有(尽管Ruby的常量只会发出警告)。Python的思维方式是,如果您想使某些内容不变,则应将变量名全部大写,而不要更改它。
例如,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
回答 4
您只能从Python中的模块导入特定功能。在Ruby中,您将导入整个方法列表。您可以在Ruby中“取消导入”它们,但这不是全部。
编辑:
让我们来看看这个Ruby模块:
module Whatever
def method1
end
def method2
end
end
如果您将其包含在代码中:
include Whatever
您会看到method1和method2都已添加到您的命名空间中。您不能仅导入method1。您要么同时导入它们,要么根本不导入它们。在Python中,您只能导入您选择的方法。如果有这个名字,也许会叫做选择性导入?
回答 5
从Ruby的网站:
与Python相似,在Ruby中,…
- 有一个交互式提示(称为irb)。
- 您可以在命令行上阅读docs(使用ri命令而不是pydoc)。
- 没有特殊的行终止符(通常的换行符除外)。
- 字符串文字可以跨越多行,例如Python的三引号字符串。
- 方括号用于列表,大括号用于字典(在Ruby中称为“哈希”)。
- 数组的工作原理相同(添加它们会构成一个长数组,但是像这样组成它们
a3 = [ a1, a2 ]
得到一个数组数组)。- 对象是强类型和动态类型的。
- 一切都是对象,变量只是对象的引用。
- 尽管关键字有些不同,但是exceptions的作用大致相同。
- 您已经拥有嵌入式doc工具(Ruby称为rdoc)。
与Python不同,在Ruby中,…
- 字符串是可变的。
- 您可以创建常量(不希望更改其值的变量)。
- 有一些强制的大小写约定(例如,类名以大写字母开头,变量以小写字母开头)。
- 列表容器只有一种(数组),并且是可变的。
- 双引号字符串允许转义序列(如\ t)和特殊的“表达式替换”语法(可让您将Ruby表达式的结果直接插入其他字符串中,而不必“添加” +“字符串” +“在一起”) 。单引号字符串类似于Python的r“原始字符串”。
- 没有“新样式”和“旧样式”类。只是一种。
- 您永远不会直接访问属性。使用Ruby,这就是所有方法调用。
- 方法调用的括号通常是可选的。
- 有公共的,私有的和受保护的用于强制访问,而不是Python的
_voluntary_ underscore __convention__
。- 使用“ mixin’s”代替多重继承。
- 您可以添加或修改内置类的方法。两种语言都可以让您随时打开和修改类,但是Python阻止了对内置函数的修改,而Ruby则不允许。
- 您将获得true和false而不是True和False(并且使用nil代替None)。
- 在测试真相时,只有false和nil会得出错误值。其他所有内容均正确(包括0、0.0,“”和[])。
- 它是elsif而不是elif。
- 这是必需的,而不是导入。否则,用法是相同的。
- 事物上方的一行(而不是它们下方的文档字符串)上的常用注释用于生成文档。
- 尽管有许多捷径可让您记住,但仍有许多捷径可让您快速学习。它们往往使Ruby变得有趣且非常有生产力。
回答 6
Ruby比Python具有的脚本语言功能。在这种情况下,脚本语言意味着用于Shell脚本和常规文本操作中的“胶水代码”。
这些大多与Perl共享。一流的内置正则表达式,$-Variables,有用的命令行选项(如Perl(-a,-e)等)。
连同其简洁而优美的语法,它非常适合此类任务。
对我而言,Python更像是一种动态类型化的业务语言,它非常易于学习并且语法简洁。不像Ruby那样“酷”,但很简洁。Python对Ruby而言,对我来说,是其他库的大量绑定。绑定到Qt和其他GUI库,许多游戏支持库以及和和。Ruby少得多。尽管经常使用的绑定(例如与数据库的绑定)具有良好的质量,但我发现利基库在Python中得到了更好的支持,即使对于同一库也有Ruby绑定。
因此,我想说这两种语言都有其用途,这是定义要使用哪种语言的任务。两者都很容易学习。我并排使用它们。Ruby用于脚本编写,Python用于独立应用程序。
回答 7
我不认为“ Ruby具有X而Python没有,而Python具有Y而Ruby没有”是查看它的最有用的方法。它们是非常相似的语言,具有许多共享功能。
在很大程度上,区别在于该语言使语言更加优雅和可读。使用您提出的示例,理论上两者都具有lambda,但是Python程序员倾向于避免使用lambda,并且使用它们构造的构造看起来不像Ruby那样易读或惯用。因此,在Python中,优秀的程序员将希望采用与Ruby中不同的方法来解决问题,只是因为这实际上是解决问题的更好方法。
回答 8
我想提出一个原始问题的变体:“ Ruby有哪些Python没有的,反之亦然?” 它承认了令人失望的答案:“那么,用Intercal无法做到的Ruby或Python可以做什么?” 在这个级别上什么都没有,因为Python和Ruby都是庞大的皇室家族的一部分,坐在图灵近似的宝座上。
但是呢:
在Python中,优雅而良好的工作可以做得很好,而在Ruby中却不能做到如此美丽和出色的工程,反之亦然?
这可能比单纯的功能比较有趣。
回答 9
Python具有用于列表推导和生成器的显式内置语法,而在Ruby中,您将使用映射和代码块。
比较
list = [ x*x for x in range(1, 10) ]
至
res = (1..10).map{ |x| x*x }
回答 10
“以大写字母开头的变量将成为常量,无法修改”
错误。他们能。
您只会收到警告。
回答 11
基础设施方面:
与Ruby相比,Python与C ++的集成要好得多(通过Boost.Python,SIP和Py ++之类的东西),而Ruby似乎可以直接针对Ruby解释器API进行编写(当然,您也可以使用Python做到这一点,但是在这两种情况下,这样做都是低级,乏味且容易出错的)或使用SWIG(虽然它可以工作,并且如果您想支持多种语言,绝对是个好主意),但它不如Boost.Python或SIP好您特别希望绑定C ++)。
Python有许多Web应用程序环境(Django,Pylons / Turbogears,web.py,可能至少还有六种),而Ruby(有效地)有一个:Rails。(确实存在其他Ruby Web框架,但是似乎很难在Rails上获得很多吸引力)。这方面是好是坏?很难说,可能很主观;我可以很容易地想到这样的论点:Python情况更好,而Ruby情况更好。
在文化上,Python和Ruby社区似乎有所不同,但是我只能暗示这一点,因为我没有与Ruby社区进行交互的丰富经验。我主要是为了补充这一点,希望对两者都有丰富经验的人可以放大(或拒绝)此声明。
回答 12
无耻地复制/粘贴自:Alex Martelli从comp.lang.python邮件列表中回答了“ Ruby比Python有什么更好的 ”线程。
2003年8月18日,上午10:50 Erik Max Francis写道:
“布兰登·范·凡·布朗”写道:
Ruby比Python有什么更好的选择?我确定有事 它是什么?
向Ruby人员(而不是Python人员)问这个不是更有意义吗?
可能(也可能不会)取决于一个人的目的-例如,如果一个人的目的包括对Python社区的“社会学研究”,那么向该社区提出问题很可能会证明有关该信息的揭示更多,而不是放在其他地方:-)。
我个人很高兴借此机会在上次OSCON上关注Dave Thomas的为期一天的Ruby教程。在语法差异的明显变化之下,我发现Ruby和Python惊人地相似-如果我正在计算几乎所有语言集中的最小生成树,我很确定Python和Ruby将成为合并的前两叶中间节点:-)。
当然,在Ruby中,我确实会在每个块的末尾键入愚蠢的“ end”(而不是不缩进)而感到疲倦-但是,我确实避免输入Python要求的同样愚蠢的’:’。每个块的 开始,所以几乎可以洗了:-)。其他语法差异,例如’@foo’与’self.foo’,或者Ruby vs Python中case的较高重要性,实际上与我无关。
毫无疑问,其他人只是基于这样的问题来选择编程语言,并且引发了最激烈的辩论-但对我而言,这只是帕金森定律中一个行动的例子(关于某个问题的辩论数量与该问题的数量成反比实际重要性)。
编辑(2010年6月19日,上午11:45之前):这也称为“为自行车棚涂漆”(或简称为“自行车棚涂漆”)-再次提及诺斯科特·帕金森,他提出了“辩论”作为“关于琐碎话题的热门辩论”的典型示例。(编辑结束)。
我确实发现语法上的差异很重要,并且对Python有利-但其他人无疑会认为相反-是“如何调用不带参数的函数”。在Python中(就像在C中一样),要调用函数,您总是要应用“调用运算符”-括号紧跟在您要调用的对象之后(在这些括号内是您在调用中传递的args,如果您没有传递参数,则括号为空)。这仅提及 任何对象,不涉及运算符,在任何上下文中都意味着仅是对对象的引用,没有特殊情况,异常,即席规则等。在Ruby中(例如在Pascal中),要调用带有WITH参数的函数,您需要传递args(通常在括号中,尽管并非总是如此)-但是,如果该函数没有args,则只需简单地提及该函数即可。这可能会满足许多人的期望(至少,毫无疑问,至少那些以前仅有编程经验的人是使用Pascal或其他具有类似“隐式调用”的语言(例如Visual Basic)的人)-但对我而言,这意味着仅提及对象可能意味着对对象的引用或对对象的调用,具体取决于对象的类型-在某些情况下,我可以 仅仅通过提及它就不能得到对对象的引用,我将需要使用明确的“给我一个对此的引用,不要称呼它!” 否则不需要的运算符。我觉得这会影响函数(或方法或其他可调用对象)的“一流”,并影响对象平滑交换的可能性。因此,对我来说,这种特定的语法差异对Ruby来说是一个严重的黑标-但我确实理解了为什么其他人会采取其他方式,即使我几乎无法强烈反对它们:-)。函数(或方法或其他可调用对象)的功能,以及顺利交换对象的可能性。因此,对我来说,这种特定的语法差异对Ruby来说是一个严重的黑标-但我确实理解了为什么其他人会采取其他方式,即使我几乎无法强烈反对它们:-)。函数(或方法或其他可调用对象)的功能,以及顺利交换对象的可能性。因此,对我来说,这种特定的语法差异对Ruby来说是一个严重的黑标-但我确实理解了为什么其他人会采取其他方式,即使我几乎无法强烈反对它们:-)。
在语法下方,我们发现了基本语义上的一些重要差异-例如,Ruby中的字符串是可变对象(例如在C ++中),而在Python中则不可改变(例如在Java中,或者我相信C#)。同样,主要根据已经熟悉的知识进行判断的人可能会认为这对Ruby有利(除非他们熟悉Java或C#,当然:-)。我,我认为不可变字符串是一个好主意(我不认为Java独立地重新发明了Python中已经存在的那个想法),尽管我也不介意具有“可变字符串缓冲区”类型(理想情况下,它比Java自己的“字符串缓冲区”具有更好的易用性);而且由于熟悉程度,我不作这样的判断-在学习Java之前, 所有数据都是不可变的,我所知道的所有语言都具有可变的字符串-但是,当我第一次看到Java中的不可变字符串的想法(我在学习Python之前就学得很好)时,它立即使我震惊,非常适合顶级编程语言的参考语义(与最适合于距离机器更近,距离应用程序更远的语言,例如C)最合适的值语义,将字符串作为一流的,内置的(漂亮的)关键)数据类型。
Ruby在基本语义上确实具有一些优势-例如,删除Python的“列表与元组”极其微妙的区别。但是大多数情况下,分数(就我而言,保持简单,是一个很大的加和微妙的,聪明的区别,是一个显着的减号)与Ruby相对(例如,同时具有封闭和半开放间隔,用符号a..b和a。表示)。 .b [任何人都想声称哪个是显而易见的?-)],这很愚蠢-当然,恕我直言!)。同样,考虑到在语言的核心上有很多相似但又细微不同的事物的人,加号(而不是减号)当然会按照我的计算方式来反加这些:-)。
这些比较不会误导您认为这两种语言是 非常不一样,请注意。他们不是。但是,如果我被要求将“ capelli d’angelo”与“ spaghettini”进行比较,然后指出这两种意大利面几乎对任何人都没有区别,并且可以在您可能要准备的任何菜肴中互换使用,那么我将不可避免地拥有进入显微镜检查长度和直径如何明显地不同,在一种情况下而不是在另一种情况下股线的末端如何逐渐变细等等,以尝试解释为什么我个人更愿意’angelo作为任何一种汤中的意大利面食,但更喜欢将意大利面条作为Pastasciutta来搭配适用于此类长而细的意大利面食形式的调味料(橄榄油,蒜末,剁碎的红辣椒和细碎的凤尾鱼,例如-但是,如果您将大蒜和胡椒切成薄片而不是切碎,那么您应该选择意大利面更健康的面条,而不是意大利面条稀薄的消失,并且建议您不要食用凤尾鱼,而应添加一些新鲜的春季罗勒[甚至-我是一个异端…!-薄荷糖…]树叶-在上菜之前的最后一刻)。糟糕,抱歉,这表明我正在国外旅行,而且有一段时间没有面食了,我想。但比喻还是相当不错的!-)-薄荷糖…]树叶-在上菜之前的最后一刻)。糟糕,抱歉,这表明我正在国外旅行,而且有一段时间没有面食了,我想。但比喻还是相当不错的!-)-薄荷糖…]树叶-在上菜之前的最后一刻)。糟糕,抱歉,这表明我正在国外旅行,而且有一段时间没有面食了,我想。但比喻还是相当不错的!-)
因此,回到Python和Ruby,我们来谈谈两个大问题(就适当的语言而言-离开了库以及其他重要辅助工具(如工具和环境,如何嵌入/扩展每种语言等),现在-它们将无法应用于每种语言的所有实现,例如,Jython与Classic Python是Python语言的两种实现!):
Ruby的迭代器和代码块与Python的迭代器和生成器;
Ruby的TOTAL不受限制的“动态性”,包括
“重新打开”任何现有类(包括所有内置类)并在运行时更改其行为的能力-相对于Python庞大但 有限的 动态性,它从未改变现有的行为内置类及其实例。就我个人而言,我认为1是一次洗礼(差异是如此之深,以至于我很容易看到人们讨厌这两种方法中的任何一种,但从我个人的角度来看,它们的优缺点几乎相同);还有2个至关重要的问题-一个使Ruby更适合“修补”的问题,但Python同样更适合用于大型生产应用程序。从某种程度上讲,这很有趣,因为两种语言都比大多数其他语言更具动态性,以至于最终它们与我的POV之间的关键区别应该取决于这一点-Ruby在这方面“达到11种”(参考当然是“ Spinal Tap”。在Ruby中我能做到!即,我可以动态地更改内置的字符串类,以便如果a == b打印“等于!\ n”,则a =“ Hello World” b =“ hello world”,否则打印“ different!\ n”,最后将打印“等于”。在python中,我无法做到这一点。出于元编程,实现实验框架等目的,Ruby的这种惊人的动态功能非常强大。 吸引人。但是-如果我们谈论的是大型应用程序,它是由许多人开发并由更多人维护的,包括来自不同来源的各种库,并且需要在客户站点上投入生产…那么,我不想一种非常动态的语言,非常感谢。我讨厌这样的想法:某些库不知不觉地打破了那些依赖于那些不同字符串的其他不相关的库-这是一种深层和深层的“通道”,在LOOK分离和应该分离的代码段之间,这意味着死亡。大规模编程。通过让任何模块“隐蔽地”影响任何其他模块的行为,对内置类型的语义进行变异的能力只是生产应用程序编程的一个坏主意,
如果我必须将Ruby用于如此大的应用程序,那么我将尝试依赖于编码样式的限制,大量的测试(只要有任何更改,都将重新运行-甚至应该完全不相关…),等等。禁止使用此语言功能。但是,我认为不首先具有该功能会更好,就像Python本身可以成为应用程序编程的一种更好的语言一样,如果可以“固定”一定数量的内置程序,那么我知道,例如len(“ ciao”)为4(而不必担心是否有人在内置模块中更改了名称“ len”的绑定…)。我确实希望Python最终能够“钉牢”其内置组件。
但是问题不大,因为重新绑定内置函数在Python中已被弃用,也是一种罕见的做法。在Ruby中,它让我感到很专业-就像 其他语言(例如Dylan)的功能过于强大一样,在我看来也存在类似的风险(我希望Python永远不会获得如此强大的宏系统, “让人们定义自己的语言中嵌入的他们自己的特定于领域的小语言”的诱惑力很重要-恕我直言,这会通过向可能的修补匠提供“有吸引力的麻烦”来削弱Python对应用程序编程的出色用处。潜伏在每个程序员的心中…)。
亚历克斯
回答 13
其他人来自:
http://www.ruby-lang.org/zh-CN/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具有多重继承。Ruby具有“ mixins”。
另一个非常相关的链接:
http://c2.com/cgi/wiki?PythonVsRuby
特别是与Alex Martelli的另一个好链接的链接,Alex Martelli在SO上也发布了很多很棒的东西:
http://groups.google.com/group/comp.lang.python/msg/028422d707512283
回答 14
我不确定,因此我首先将其添加为答案。
Python将未绑定方法视为函数
这意味着您可以通过theobject.themethod()
或调用方法TheClass.themethod(anobject)
。
编辑:尽管方法和函数之间的差异在Python中很小,在Python 3中不存在,但是在Ruby中也不存在,仅因为Ruby没有函数。定义函数时,实际上是在Object上定义方法。
但是您仍然不能采用一个类的方法并将其作为函数调用,您将不得不将其重新绑定到要调用的对象上,这更加令人费解。
回答 15
我想提到Python描述符API,该API允许一个自定义对象到属性的“通信”。还值得注意的是,在Python中,可以通过覆盖通过方法的默认实现提供的默认值来自由实现另一种协议__getattribute__
。让我提供有关上述内容的更多详细信息。描述是在普通类__get__
,__set__
和/或__delete__
方法。当解释器遇到类似的内容时anObj.anAttr
,将执行以下操作:
__getattribute__
的方法anObj
被调用__getattribute__
从类字典中检索anAttr对象- 它检查abAttr对象是否具有
__get__
,__set__
或__delete__
可调用对象 - 上下文(即调用方对象或类,以及值,而不是后者,如果有设置器的话)被传递给可调用对象
- 返回结果。
如前所述,这是默认行为。可以通过重新实现自由更改协议__getattribute__
。
该技术比装饰器功能强大得多。
回答 16
Ruby使用内置了延续支持callcc
。
因此,您可以实施酷的东西,例如amb-operator
回答 17
在此阶段,Python仍具有更好的unicode支持
回答 18
Python具有文档字符串,而ruby没有…或者,如果没有,则无法像在python中那样容易地访问它们。
附言 如果我错了,请留下一个例子?我有一个解决方法,可以很容易地将其Monkey类拼凑到类中,但是我想以“本机方式”使用文档字符串有点功能。
回答 19
Ruby在命令行中逐行循环输入文件(’-n’标志),因此可以像AWK一样使用。这个Ruby一线:
ruby -ne 'END {puts $.}'
将计数像AWK一线式的行:
awk 'END{print NR}'
Ruby通过Perl获得了此功能,Perl从AWK那里获得了它,这是使系统管理员可以使用Perl的一种方式,而不必更改他们的工作方式。
回答 20
Ruby有Sigils和Twigils,Python没有。
编辑:这是我忘记的一个非常重要的事情(毕竟,前一个只是发火了一点:-p):
Python具有JIT编译器(Psyco),一种用于编写更快的代码的低级语言(Pyrex)和添加内联C ++代码(Weave)的能力。
回答 21
我的python生锈了,所以其中一些可能在python中,我只是一开始就不记得/从未学过,但是这里是我想到的前几个:
空格
Ruby处理空白完全不同。对于初学者,您不需要缩进任何内容(这意味着使用4个空格或1个制表符都没有关系)。它还执行智能线路连续,因此以下内容有效:
def foo(bar,
cow)
基本上,如果您以运算符结尾,它将找出正在发生的事情。
混合蛋白
Ruby具有可以扩展实例而不是完整类的mixin:
module Humor
def tickle
"hee, hee!"
end
end
a = "Grouchy"
a.extend Humor
a.tickle » "hee, hee!"
枚举
我不确定这是否与生成器相同,但是从Ruby 1.9 ruby开始,作为枚举,所以
>> enum = (1..4).to_enum
=> #<Enumerator:0x1344a8>
参考:http : //blog.nuclearsquid.com/writings/ruby-1-9-what-s-new-what-s-changed
“关键字参数”
尽管您不能跳过这样的默认值,但Ruby中支持其中列出的两个项目。你可以按顺序去
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。
或者您也可以使用散列来解决第二个问题
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实用程序员指南》
回答 22
您可以在Ruby和Python的类定义中都包含代码。但是,在Ruby中,您有对类(自身)的引用。在Python中,您没有对该类的引用,因为该类尚未定义。
一个例子:
class Kaka
puts self
end
在这种情况下,self是类,并且此代码将打印出“ Kaka”。无法打印出类名,也无法通过其他方式从Python中的类定义主体访问该类。
回答 23
语法不是一件小事,它直接影响我们的思维方式。它也直接影响我们为使用的系统创建的规则。例如,由于我们编写数学方程式或句子的方式,我们具有运算顺序。数学的标准表示法允许人们以多种方式阅读它,并在给定相同方程的情况下得出不同的答案。如果我们使用前缀或后缀表示法,那么我们将创建规则以区分要操纵的数字,而不是仅具有计算值顺序的规则。
标准表示法清楚地表明了我们在谈论什么数字,同时使它们的计算顺序不明确。前缀和后缀表示法在使数字含糊不清的同时,使计算明文的顺序变得容易。如果不是因为语法空白引起的困难,Python就已经有了多行lambda。(确实存在一些建议,无需添加显式的块定界符就可以拉出此类内容。)
我发现在条件为假的情况下编写条件(如果条件为假)要比在Ruby或其他语言中用语义上等效的“ if-not”构造容易得多,而用Ruby语句中的else语句更容易编写条件。如果当今人们使用的大多数语言的力量相等,那么如何将每种语言的语法视为琐碎的事情呢?在诸如块和继承机制等特定功能之后,语法是语言最重要的部分,这并不是肤浅的事情。
肤浅的是我们赋予句法的美的美学特质。美学与我们的认知如何运作,语法无关。
回答 24
惊讶地发现红宝石的“方法缺失”机制一无所获。我将提供Rails中find_by _…方法的示例,作为该语言功能强大功能的示例。我的猜测是可以在Python中实现类似的功能,但据我所知它本身并不存在。
回答 25
Paul Graham的累加器生成器问题证明了Python和Ruby在lambda上的另一个区别。转载在这里:
编写一个具有数字n的函数foo,并返回一个具有数字i的函数,并返回以i递增的n。注意:(a)是数字而不是整数,(b)是递增而不是加号。
在Ruby中,您可以执行以下操作:
def foo(n)
lambda {|i| n += i }
end
在Python中,您将创建一个对象来保存n的状态:
class foo(object):
def __init__(self, n):
self.n = n
def __call__(self, i):
self.n += i
return self.n
有些人可能更喜欢显式Python方法,因为它在概念上更加清晰,即使它有些冗长。您可以像存储其他任何内容一样存储状态。您只需要围绕可调用对象的想法就可以了。但是,无论人们从审美角度偏爱哪种方法,它的确表明了一个方面,即Ruby lambda比Python更强大。
回答 26
python已命名可选参数
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仅定位参数,因为函数声明中的b = 2是始终附加的影响。
回答 27
Ruby嵌入了文档:
=begin
You could use rdoc to generate man pages from this documentation
=end
回答 28
http://c2.com/cgi/wiki?PythonVsRuby
http://c2.com/cgi/wiki?SwitchedFromPythonToRuby
http://c2.com/cgi/wiki?SwitchedFromRubyToPython
http://c2.com/cgi/wiki使用PythonDontNeedPython
http://c2.com/cgi/wiki
回答 29
在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”