有很多关于Python与Ruby的讨论,我发现它们完全没有用,因为它们都转向了为什么功能X在语言Y中很糟糕,或者声称语言Y没有X,尽管事实上确实如此.我也确切地知道为什么我更喜欢Python,但这也是主观的,并且不会帮助任何人选择,因为他们可能没有和我一样的开发品味.
因此,客观地列出差异将是有趣的.所以没有"Python的lambdas糟透了".而是解释Ruby的lambdas可以做什么,Python不能.没有主观性.示例代码很好!
请不要在一个答案中有几个不同之处.并且对那些你认识的是正确的进行投票,然后对你所知道的那些是不正确的(或者是主观的).此外,语法上的差异也不大.我们知道Python使用缩进来处理Ruby用括号和结尾做什么,并且@在Python中称为self.
更新:这是一个社区维基,所以我们可以在这里添加很大的差异.
在Ruby中,您可以在类主体中引用类(self).在Python中,在类构造完成之前,您没有对类的引用.
一个例子:
class Kaka
puts self
end
Run Code Online (Sandbox Code Playgroud)
在这种情况下,self就是类,这段代码会打印出"Kaka".无法打印出类名或以其他方式从Python中的类定义体(外部方法定义)访问该类.
这使您可以开发核心类的扩展.以下是rails扩展的示例:
class String
def starts_with?(other)
head = self[0, other.length]
head == other
end
end
Run Code Online (Sandbox Code Playgroud)
Python(想象没有''.startswith方法):
def starts_with(s, prefix):
return s[:len(prefix)] == prefix
Run Code Online (Sandbox Code Playgroud)
您可以在任何序列(不仅仅是字符串)上使用它.为了使用它,你应该明确地导入它,例如,from some_module import starts_with.
Ruby拥有一流的regexp,$ -variables,awk/perl逐行输入循环和其他功能,使其更适合编写munge文本文件的小shell脚本或充当其他程序的粘合代码.
感谢callcc声明.在Python中,您可以通过各种技术创建延续,但是该语言没有内置支持.
使用"do"语句,您可以在Ruby中创建一个多行匿名函数,它将作为参数传递到do前面的方法中,并从那里调用.在Python中,您可以通过传递方法或使用生成器来执行此操作.
红宝石:
amethod { |here|
many=lines+of+code
goes(here)
}
Run Code Online (Sandbox Code Playgroud)
Python(Ruby块对应于Python中的不同构造):
with amethod() as here: # `amethod() is a context manager
many=lines+of+code
goes(here)
Run Code Online (Sandbox Code Playgroud)
要么
for here in amethod(): # `amethod()` is an iterable
many=lines+of+code
goes(here)
Run Code Online (Sandbox Code Playgroud)
要么
def function(here):
many=lines+of+code
goes(here)
amethod(function) # `function` is a callback
Run Code Online (Sandbox Code Playgroud)
有趣的是,Ruby中用于调用块的便捷语句称为"yield",在Python中将创建一个生成器.
红宝石:
def themethod
yield 5
end
themethod do |foo|
puts foo
end
Run Code Online (Sandbox Code Playgroud)
蟒蛇:
def themethod():
yield 5
for foo in themethod():
print foo
Run Code Online (Sandbox Code Playgroud)
虽然原则不同,但结果却非常相似.
myList.map(&:description).reject(&:empty?).join("\n")
Run Code Online (Sandbox Code Playgroud)
蟒蛇:
descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))
Run Code Online (Sandbox Code Playgroud)
Python支持该语言的生成器.在Ruby 1.8中,您可以使用生成器模块,该模块使用continuation从块创建生成器.或者,您可以使用块/ 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]
Run Code Online (Sandbox Code Playgroud)
将其与上述块示例进行对比.
在Ruby中,当您导入文件时require,该文件中定义的所有内容都将在您的全局命名空间中结束.这导致命名空间污染.解决方案是Rubys模块.但是,如果使用模块创建命名空间,则必须使用该命名空间来访问包含的类.
在Python中,文件是一个模块,您可以导入其包含的名称from themodule import *,从而在需要时污染命名空间.但您也可以使用from themodule import aname, another或只是导入选定的名称,import themodule然后使用themodule.aname.如果您希望在命名空间中有更多级别,则可以使用包,这些包是包含模块和__init__.py文件的目录.
Docstrings是附加到模块,函数和方法的字符串,可以在运行时进行内省.这有助于创建帮助命令和自动文档等内容.
def frobnicate(bar):
"""frobnicate takes a bar and frobnicates it
>>> bar = Bar()
>>> bar.is_frobnicated()
False
>>> frobnicate(bar)
>>> bar.is_frobnicated()
True
"""
Run Code Online (Sandbox Code Playgroud)
Ruby的等价物类似于javadocs,位于方法之上而不是在其中.可以使用1.9的Method#source_location 示例使用在运行时从文件中检索它们
Ruby没有("故意" - 请参阅Ruby的网站,请参阅此处如何在Ruby中完成).它确实将模块概念重用为一种抽象类.
蟒蛇:
res = [x*x for x in range(1, 10)]
Run Code Online (Sandbox Code Playgroud)
红宝石:
res = (0..9).map { |x| x * x }
Run Code Online (Sandbox Code Playgroud)
蟒蛇:
>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7c1ccd4>
>>> list(_)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Run Code Online (Sandbox Code Playgroud)
红宝石:
p = proc { |x| x * x }
(0..9).map(&p)
Run Code Online (Sandbox Code Playgroud)
Python 2.7+:
>>> {x:str(y*y) for x,y in {1:2, 3:4}.items()}
{1: '4', 3: '16'}
Run Code Online (Sandbox Code Playgroud)
红宝石:
>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}
Run Code Online (Sandbox Code Playgroud)
类似于装饰器的东西也可以用Ruby创建,也可以说它们不像Python那样必要.
Ruby需要"end"或"}"来关闭它的所有作用域,而Python只使用white-space.最近Ruby已经尝试允许只有空格的缩进http://github.com/michaeledgar/seamless
Joh*_*lla 34
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
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样调用它:
# Add five to each element.
[1, 2, 3, 4].each{ |e| puts e + 5 }
> [6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)
Python有匿名函数/闭包/ lambdas,但它没有完全有块,因为它缺少一些有用的语法糖.但是,至少有一种方法可以以临时方式获得它.例如,请参见此处.
Gle*_*ard 28
函数是Python中的第一类变量.您可以声明一个函数,将其作为对象传递,并覆盖它:
def func(): print "hello"
def another_func(f): f()
another_func(func)
def func2(): print "goodbye"
func = func2
Run Code Online (Sandbox Code Playgroud)
这是现代脚本语言的基本特征.JavaScript和Lua也这样做.Ruby不会以这种方式处理函数; 命名函数调用它.
当然,有很多方法可以在Ruby中做这些事情,但它们不是一流的操作.例如,您可以使用Proc.new包装函数将其视为变量 - 但它不再是函数; 它是一个带有"调用"方法的对象.
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!"
Run Code Online (Sandbox Code Playgroud)
Mar*_*mas 26
最终所有的答案在某种程度上都是主观的,到目前为止发布的答案几乎证明了你不能指出任何一种在另一种语言中不可行的功能同样不错(如果不是相似)的方式因为这两种语言都非常简洁和富有表现力.
我喜欢Python的语法.但是,你必须比语法更深入地挖掘Ruby的真正美.Ruby的一致性具有禅宗般的美感.虽然没有一个简单的例子可以完全解释这一点,但我会试着在这里提出一个来解释我的意思.
反转此字符串中的单词:
sentence = "backwards is sentence This"
Run Code Online (Sandbox Code Playgroud)
当您考虑如何做到这一点时,您将执行以下操作:
在Ruby中,你会这样做:
sentence.split.reverse.join ' '
Run Code Online (Sandbox Code Playgroud)
正如你所想的那样,在同一个序列中,一个方法一个接一个地调用.
在python中,它看起来更像是这样的:
" ".join(reversed(sentence.split()))
Run Code Online (Sandbox Code Playgroud)
这并不难理解,但它并没有完全相同的流程.主语(句子)埋在中间.这些操作是函数和对象方法的混合.这是一个简单的例子,但是当真正使用和理解Ruby时,会发现许多不同的例子,特别是在非平凡的任务上.
Jas*_*ker 18
Python有一个"我们都是成年人在这里"的心态.因此,你会发现Ruby有像常量这样的东西,而Python却没有(尽管Ruby的常量只会引发警告).Python的思维方式是,如果你想使某些东西保持不变,你应该将变量名称放在所有大写字母中而不是改变它.
例如,Ruby:
>> PI = 3.14
=> 3.14
>> PI += 1
(irb):2: warning: already initialized constant PI
=> 4.14
Run Code Online (Sandbox Code Playgroud)
蟒蛇:
>>> PI = 3.14
>>> PI += 1
>>> PI
4.1400000000000006
Run Code Online (Sandbox Code Playgroud)
Geo*_*Geo 18
您只能从Python中导入模块中的特定函数.在Ruby中,您可以导入整个方法列表.你可以在Ruby中"取消"它们,但它并不是它的全部内容.
编辑:
让我们来看看这个Ruby模块:
module Whatever
def method1
end
def method2
end
end
Run Code Online (Sandbox Code Playgroud)
如果你把它包含在你的代码中:
include Whatever
Run Code Online (Sandbox Code Playgroud)
你会看到method1和method2都已添加到你的命名空间中.您不能仅导入method1.您可以同时导入它们,也可以根本不导入它们.在Python中,您只能导入您选择的方法.如果这个名称可能会被称为选择性导入?
小智 16
来自Ruby的网站:
相似之处与Python一样,在Ruby中......
- 有一个交互式提示(称为irb).
- 您可以在命令行上读取文档(使用ri命令而不是pydoc).
- 没有特殊的行终止符(通常的换行符除外).
- 字符串文字可以跨越多行,如Python的三引号字符串.
- 括号用于列表,括号用于dicts(在Ruby中,称为"哈希").
- 数组的工作方式相同(添加它们会产生一个长数组,但是像这样组成它们
a3 = [ a1, a2 ]会给你一个数组数组).- 对象强烈且动态地键入.
- 一切都是对象,变量只是对象的引用.
- 虽然关键字有点不同,但异常的工作方式大致相同.
- 你有嵌入式doc工具(Ruby的名字叫做rdoc).
差异与Python不同,在Ruby中......
- 字符串是可变的.
- 您可以创建常量(您不打算更改其值的变量).
- 有一些强制执行的案例约定(例如,类名以大写字母开头,变量以小写字母开头).
- 只有一种列表容器(一个数组),它是可变的.
- 双引号字符串允许转义序列(如\ t)和特殊的"表达式替换"语法(允许您将Ruby表达式的结果直接插入到其他字符串中,而无需"添加"+"字符串"+"在一起") .单引号字符串就像Python的r"原始字符串".
- 没有"新风格"和"旧风格"课程.只是一种.
- 您永远不会直接访问属性.使用Ruby,它是所有方法调用.
- 方法调用的括号通常是可选的.
- 有公共,私有和受保护来强制访问,而不是Python
_voluntary_ underscore __convention__.- 使用"mixin"而不是多重继承.
- 您可以添加或修改内置类的方法.这两种语言都可以让你随时打开和修改类,但是Python阻止了对内置函数的修改 - 而Ruby则没有.
- 你有真和假而不是真和假(和零而不是无).
- 当测试真相时,只有false和nil评估为假值.其他一切都是真的(包括0,0.0,""和[]).
- 这是elsif而不是elif.
- 它需要而不是导入.否则,用法是一样的.
- 关于事物上面的行(而不是它们下面的文档字符串)的通常风格的注释用于生成文档.
- 有许多快捷方式,虽然可以让你记住更多,但你很快就会学到.他们倾向于使Ruby变得有趣并且非常高效.
haf*_*fax 12
Ruby拥有的是它的脚本语言功能.在此上下文中的脚本语言意味着在shell脚本和一般文本操作中用于"粘合代码".
这些主要与Perl共享.一流的内置正则表达式,$ -Variables,有用的命令行选项,如Perl(-a,-e)等.
结合其简洁而又灵巧的语法,它非常适合这类任务.
Python对我来说更像是一种动态类型的商业语言,它非常容易学习并且语法清晰.不像Ruby那样酷"但很整洁".Python对我来说是对其他lib的大量绑定.绑定到Qt和其他GUI库,许多游戏支持库和和.Ruby少得多.虽然很多用于数据库的绑定具有良好的质量,但我发现在Python中更好地支持利基库,即使对于相同的库也存在Ruby绑定.
所以,我会说两种语言都有它的用途,它的任务是定义使用哪种语言.两者都很容易学习.我并排使用它们.用于脚本的Ruby和用于独立应用程序的Python.
Chu*_*uck 12
我不认为"Ruby有X而Python没有,而Python有Y而Ruby没有"是最有用的方式来看待它.它们是非常相似的语言,具有许多共享能力.
在很大程度上,差异在于语言的优雅和可读性.使用你提出的一个例子,理论上它们都有lambdas,但Python程序员倾向于避免它们,并且使用它们构造的构造看起来不像Ruby那样可读或惯用.所以在Python中,一个优秀的程序员会想要采用不同的方法来解决问题而不是Ruby,因为它实际上是更好的方法.
Chr*_*ard 12
我想建议一个原始问题的变体,"Ruby有什么不具备Python,反之亦然?" 它承认了令人失望的答案,"那么,你能用Ruby或者Python做什么,而Intercal无法做到这一点?" 在这个层面上没有任何东西,因为Python和Ruby都是坐在图灵近似宝座上的庞大王室的一部分.
但是这个怎么样:
什么可以在Python中优雅地完成,而不能在具有如此美丽和良好工程的Ruby中完成,反之亦然?
这可能比仅仅进行功能比较更有趣.
Dar*_*rio 11
Python有一个用于list-comprehenions和generator的显式内置语法,而在Ruby中你可以使用map和code blocks.
相比
list = [ x*x for x in range(1, 10) ]
Run Code Online (Sandbox Code Playgroud)
至
res = (1..10).map{ |x| x*x }
Run Code Online (Sandbox Code Playgroud)
小智 11
"以大写字母开头的变量变为常量,无法修改"
错误.他们能.
如果你这样做,你只会收到警告.
Jac*_*oyd 11
在基础设施方面更多:
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社区交互的经验.我主要是希望那些对两者都有很多经验的人可以放大(或拒绝)这种说法.
Osc*_*Ryz 11
无耻地复制/粘贴来自:亚历克斯·马尔泰利的答案对" 什么是关于Ruby比Python更好 "从线程comp.lang.python的邮件列表.
2003年8月18日上午10点50分,Erik Max Francis写道:
"Brandon J. Van Every"写道:
Ruby比Python有什么好处?我确定有一些东西.它是什么?
问问Ruby人员而不是Python人员会不会更有意义?
可能会,也可能不会,取决于一个人的目的 - 例如,如果一个人的目的包括Python社区的"社会学研究",那么向该社区提出问题可能会更多地揭示有关它的信息,而不是将它们放在其他地方:-).
Personally, I gladly took the opportunity to follow Dave Thomas' one-day Ruby tutorial at last OSCON. Below a thin veneer of syntax differences, I find Ruby and Python amazingly similar -- if I was computing the minimum spanning tree among just about any set of languages, I'm pretty sure Python and Ruby would be the first two leaves to coalesce into an intermediate node:-).
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).
我发现一个重要的语法差异,并且有利于Python - 但其他人无疑会认为恰恰相反 - 是"你怎么称呼一个不带参数的函数".在Python中(比如在C中),要调用一个函数,你总是应用"调用操作符" - 在你调用的对象之后的尾随括号(在那些尾随括号内)去你在调用中传递的args - 如果你没有传递args,那么括号是空的).这仅仅提到了 任何一个 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:-).
在语法下面,我们在基本语义学中遇到了一些重要的差异 - 例如,Ruby中的字符串是可变对象(比如在C++中),而在Python中它们是不可变的(比如在Java中,或者我相信C#).同样,主要通过他们已经熟悉的东西来判断的人可能认为这对Ruby来说是一个加分(除非他们熟悉Java或C#,当然:-).我,我认为不可变的字符串是一个很好的想法(我并不奇怪Java,我认为,它重新发明了已经在Python中的那个想法),尽管我不介意拥有"可变字符串缓冲区"类型(理想情况下,它比Java自己的"字符串缓冲区"更易于使用); 在学习Java之前,我不会因为熟悉而给出这个判断, 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在基本语义方面确实有一些优势 - 例如,删除Python的"列表与元组"非常微妙的区别.但主要是得分(因为我保持它,简单是一个大的加分和微妙的,聪明的区别,一个显着的减去)是对Ruby(例如,有闭合和半开放的间隔,符号a..b和.. .b [任何人都想声称这显然是哪个? - )],当然是傻 - 恕我直言!).再一次,那些认为在语言的核心有很多相似但略有不同的东西的人,而不是MINUS,当然会将这些"另一种方式"从我如何计算中算起来:-).
不要被这些比较误导,认为这两种语言 非常相似不同,请注意.他们不是.但是,如果我被要求将"capelli d'angelo"与"spaghettini"进行比较,在指出这两种意大利面几乎与任何人无法区分并且可以在任何你想要准备的菜中互换时,我将不可避免地要进入显微镜检查长度和直径如何不知不觉地变化,如何在一个案例中而不是在另一个案例中使股线的末端逐渐变细,等等 - 试图解释为什么我个人宁愿有capelli d 'angelo作为任何种类的肉汤中的意大利面,但更喜欢spaghettini作为pastasciutta与适当的调味汁配合如此长的薄面食形式(橄榄油,蒜末,切碎的红辣椒和精细的凤尾鱼,例如 - 但如果你切大蒜和辣椒而不是切碎它们,那么你应该选择意大利面条的发声器体而不是spaghettini的更薄的消逝,并且建议放弃achovies并添加一些新鲜的春天罗勒[甚至 - 我是异教徒......! - 薄荷......叶子 - 在送餐前的最后一刻).哎呀,抱歉,这表明我正在国外旅行,并且暂时没有意大利面,我想.但这个比喻还是不错的! - ) - 薄荷......叶子 - 在送餐前的最后一刻).哎呀,抱歉,这表明我正在国外旅行,并且暂时没有意大利面,我想.但这个比喻还是不错的! - ) - 薄荷......叶子 - 在送餐前的最后一刻).哎呀,抱歉,这表明我正在国外旅行,并且暂时没有意大利面,我想.但这个比喻还是不错的! - )
所以,回到Python和Ruby,我们来看两个大问题(就语言本身而言 - 离开库,以及其他重要的辅助工具,如工具和环境,如何嵌入/扩展每种语言等等),它现在 - 它们不会适用于每种语言的所有实现,例如,Jython vs Classic Python是Python语言的两个实现!):
Ruby的迭代器和代码块与Python的迭代器和生成器相比;
Ruby的TOTAL,肆无忌惮的"动态性",包括
"重新打开"任何现有类的能力,包括所有内置类,并在运行时改变其行为 - 与Python的巨大但 有限的 动态性相比,它永远不会改变现有的行为内置类及其实例.就个人而言,我认为1一洗(差异是如此之深,我可以很容易地看到人们憎恨任何一种方法和尊崇等,但就我个人的尺度优缺点只是甚至达到); 和2的一个关键问题-一个使Ruby更适合"修修补补",但是Python同样更适合在大型生产应用.在某种程度上,这很有趣,因为两种语言都比其他语言更具动态性,最终它们与我的POV之间的关键区别应该取决于那个 - 在这方面Ruby"十一"(参考文献)这里是"Spinal Tap",当然).在Ruby中,我能做到!即,我可以动态地改变内置字符串类,以便a ="Hello World"b ="hello world"如果a == b打印"相等!\n"否则打印"不同!\n"结束将打印"等于".在python中,我无法做到这一点.出于元编程,实现实验框架等目的,Ruby的这种惊人的动态能力非常强大 吸引力.但是 - 如果我们谈论的是大型应用程序,由许多人开发并且由更多人维护,包括来自不同来源的各种库,并且需要在客户端站点投入生产......好吧,我不想要一种非常动态的QUITE语言,非常感谢你.我厌恶一些图书馆的想法,无意中打破了依赖于那些不同字符串的其他不相关的图书馆 - 这就是那种深层隐藏的"渠道",在LOOK分开并且应该分开的代码之间,大规模的编程.通过让任何模块影响任何其他"隐蔽"的行为,改变内置类型的语义的能力只是生产应用程序编程的一个不好的想法,
如果我不得不将Ruby用于这么大的应用程序,我会尝试依赖编码风格的限制,大量的测试(无论什么时候改变都要重新运行 - 甚至应该完全无关......),等等,禁止使用此语言功能.但是在我看来,没有首先使用该功能甚至更好 - 正如Python本身对于应用程序编程来说是更好的语言,如果一定数量的内置命令可能被"钉死",那么我就知道了例如,len("ciao")是4(而不必担心是否有人在内置模块中更改了名称'len'的绑定...).我希望最终Python能够"确定"其内置插件.
但这个问题很小,因为重新绑定内置函数在Python中已经被弃用了,也是一种罕见的做法.在Ruby中,它让我觉得很重要 - 就像 其他语言的功能太强大(例如,Dylan)在我看来存在类似风险一样(我希望Python永远不会得到如此强大的宏系统,不重要的是"让人们定义他们自己的语言本身嵌入的特定领域的小语言" - 恕我直言,它会削弱Python对应用程序编程的极大用处,通过向可能的修补匠提出"有吸引力的麻烦"潜伏在每个程序员心中...).
亚历克斯
其他一些来自:
http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-python/
(如果因为该页面已更新,我在Ruby方面有任何错误或任何这些已经改变,有人可以自由编辑...)
字符串在Ruby中是可变的,而不是在Python中(其中新字符串由"更改"创建).
Ruby有一些强制执行的案例约定,而Python没有.
Python有列表和元组(不可变列表).Ruby具有与Python列表对应的数组,但没有不可变的变体.
在Python中,您可以直接访问对象属性.在Ruby中,它总是通过方法.
在Ruby中,方法调用的括号通常是可选的,但在Python中则不行.
Ruby具有public,private和protected来强制访问,而不是Python使用下划线和名称修改的约定.
Python有多重继承.Ruby有"mixins".
另一个非常相关的链接:
http://c2.com/cgi/wiki?PythonVsRuby
尤其是亚历克斯·马尔泰利(Alex Martelli)与其他优秀人物的联系,他也在SO上发布了很多很棒的东西:
http://groups.google.com/group/comp.lang.python/msg/028422d707512283
我不确定这一点,所以我先把它作为答案添加.
这意味着你可以调用一个方法要么喜欢theobject.themethod()或通过TheClass.themethod(anobject).
编辑:虽然方法和函数之间的差异在Python中很小,而在Python 3中不存在,但它在Ruby中也不存在,仅仅因为Ruby没有函数.定义函数时,实际上是在Object上定义方法.
但你仍然不能采用一个类的方法并将其作为一个函数调用,你必须将它重新绑定到你想要调用的对象,这是更加顽固的.
小智 7
我想提一下Python描述符API,它允许一个自定义对象到属性的"通信".值得注意的是,在Python中,可以通过覆盖通过方法的默认实现给出的默认值来自由地实现替代协议__getattribute__.让我提供有关上述内容的更多细节.描述是在普通类__get__,__set__和/或__delete__方法.当解释器遇到类似的东西时anObj.anAttr,执行以下操作:
__getattribute__方法anObj被调用__getattribute__ 从类dict中检索anAttr对象__get__,__set__或__delete__可调用对象如前所述,这是默认行为.可以通过重新实现来自由地更改协议__getattribute__.
这种技术比装饰器更强大.
您可以在Ruby和Python中的类定义中包含代码.但是,在Ruby中,您可以引用类(self).在Python中,您没有对类的引用,因为该类尚未定义.
一个例子:
class Kaka
puts self
end
Run Code Online (Sandbox Code Playgroud)
在这种情况下,self就是类,这段代码会打印出"Kaka".无法打印出类名或以其他方式从Python中的类定义主体访问该类.
Python有文档字符串,ruby没有......或者如果没有,它们就像在python中一样容易访问.
PS.如果我错了,请多好,留下一个例子?我有一个解决方法,我可以非常容易地monkeypatch到类,但我想在"本地方式"有文档字符串类型的功能.
Ruby在命令行中对输入文件('-n'标志)进行逐行循环,因此可以像AWK一样使用.这个Ruby单线程:
ruby -ne 'END {puts $.}'
Run Code Online (Sandbox Code Playgroud)
将计算像AWK单线的线:
awk 'END{print NR}'
Run Code Online (Sandbox Code Playgroud)
Ruby通过Perl获取功能,Perl将其从AWK中获取,作为一种使用Perl获取系统管理员的方法,而无需改变他们的工作方式.
我的python生锈了,所以其中一些可能是在python中,我只是不记得/从未学习过,但这里是我想到的前几个:
Ruby处理完全不同的空白.对于初学者,您不需要缩进任何内容(这意味着如果使用4个空格或1个选项卡则无关紧要).它还可以进行智能线路延续,因此以下内容有效:
def foo(bar,
cow)
Run Code Online (Sandbox Code Playgroud)
基本上,如果你以一个操作员结束,它会弄清楚发生了什么.
Ruby有mixins,它可以扩展实例而不是完整的类:
module Humor
def tickle
"hee, hee!"
end
end
a = "Grouchy"
a.extend Humor
a.tickle » "hee, hee!"
Run Code Online (Sandbox Code Playgroud)
我不确定这是否与生成器相同,但是从Ruby 1.9 ruby作为枚举,所以
>> enum = (1..4).to_enum
=> #<Enumerator:0x1344a8>
Run Code Online (Sandbox Code Playgroud)
参考:http://blog.nuclearsquid.com/writingings/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
Run Code Online (Sandbox Code Playgroud)
注意,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
Run Code Online (Sandbox Code Playgroud)
参考:实用的Progammer Ruby指南
| 归档时间: |
|
| 查看次数: |
125425 次 |
| 最近记录: |