title中文 - python画大图




Ruby不具备Python的功能,反之亦然? (20)

有很多关于Python和Ruby的讨论,我都发现它们完全没有帮助,因为它们都反过来说明为什么特性X在语言Y中很糟糕,或者说声明语言Y没有X,尽管事实上它确实如此。 我也确切知道为什么我更喜欢Python,但这也是主观的,并且不会帮助任何人选择,因为他们可能没有像我一样的开发口味。

客观地列出这些差异是很有趣的。 所以没有“Python的lambdas糟糕”。 相反,请解释一下Ruby的lambda表达式可以做到Python不能做到的事情。 没有主观性。 示例代码很好!

请不要在一个答案中有几处不同。 并且投票你知道的是正确的,并且那些你知道的是不正确的(或者是主观的)。 另外,语法上的差异并不令人感兴趣。 我们知道Python会使用缩进的方式来处理括号和结尾,而在Python中@被称为self。

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

Ruby在类体中有一个类引用

在Ruby中,你已经在类体中引用了类(self)。 在Python中,只有在类构造完成之后,才能引用该类。

一个例子:

class Kaka
  puts self
end

在这种情况下,自己就是班级,这段代码会打印出“卡卡”。 无法打印出类名或以其他方式从Python中的类定义主体(方法定义外部)访问该类。

所有类在Ruby中都是可变的

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

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具有第一类正则表达式,$ -variables,awk / perl逐行输入循环和其他功能,使其更适合编写嵌入文本文件的小型shell脚本或充当其他程序的粘合代码。

Ruby有一流的延续

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

Ruby有块

使用“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

蟒蛇:

def themethod():
    yield 5

for foo in themethod():
    print foo

虽然原理不同,但结果却非常相似。

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

myList.map(&:description).reject(&:empty?).join("\n")

蟒蛇:

descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))

Python有内置的生成器(像上面提到的那样使用Ruby块)

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]

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

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

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

在Python中,该文件是一个模块,您可以使用from themodule import *导入其包含的名称,从而如果需要则会污染命名空间。 但是,您也可以使用from themodule import aname, another导入选定的名称,也可以只import themodule ,然后使用import themodule访问名称。 如果你想在你的命名空间中有更多的级别,你可以使用包,它们是带有模块和__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有list / dict理解

蟒蛇:

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

红宝石:

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

蟒蛇:

>>> (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需要“结束”或“}”来关闭它的所有范围,而Python只使用空白。 最近在Ruby中尝试仅允许空格缩进http://github.com/michaeledgar/seamless


In Ruby, when you import a file with require, all the things defined in that file will end up in your global namespace.

通过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"

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

Python有一个“我们都是大人”的心态。 因此,你会发现Ruby具有类似常量的东西,而Python不具备这种功能(尽管Ruby的常量只会引发警告)。 Python的思维方式是,如果你想使某些东西保持不变,你应该把变量名放在所有大写字母中,而不要改变它。

例如,Ruby:

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

蟒蛇:

>>> PI = 3.14
>>> PI += 1
>>> PI
4.1400000000000006

Python有一个明确的内置语法,用于列表扩展和生成器,而在Ruby中则使用map和代码块。

比较

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

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

Ruby对Python的支持是它的脚本语言功能。 脚本语言在这种情况下意味着用于shell脚本中的“胶合代码”和一般的文本操作。

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

再加上其简洁而又不失代表性的语法,这对于这些任务来说是完美的。

Python对我来说更多的是一种动态类型的商业语言,它非常容易学习,并且语法简洁。 不像Ruby那么“酷”,但整洁。 Python对我来说有什么是其他库的大量绑定。 绑定到Qt和其他GUI库,许多游戏支持库和和。 Ruby少得多。 虽然很多使用的绑定例如数据库质量很好,但我发现在Python中更好地支持小众库,即使对于同一个库也有一个Ruby绑定。

所以,我会说两种语言都有它的用处,而且它的任务是定义使用哪一种语言。 两者都很容易学习。 我并排使用它们。 用于脚本的Ruby和用于独立应用程序的Python。



无耻复制/粘贴: Alex Martelli从comp.lang.python邮件列表中回答Ruby比Python更好 ”的主题。

2003年8月18日上午10点50分Erik Max Francis写道:

“Brandon J. Van Every”写道:

Ruby比Python更好? 我确定有什么。 它是什么?

问问Ruby这个人而不是Python人会更有意义吗?

根据用户的目的,可能会或可能不会,例如,如果用户的目的包括Python社区的“社会学研究”,那么向该社区提出问题可能会更多地揭示关于它的信息,而不是将它们放在其他地方:-)。

就我个人而言,我很高兴借此机会在最后OSCON关注Dave Thomas的为期一天的Ruby教程。 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).

One syntax difference that I do find important, and in Python's favor -- but other people will no doubt think just the reverse -- is "how do you call a function which takes no parameters". In Python (like in C), to call a function you always apply the "call operator" -- trailing parentheses just after the object you're calling (inside those trailing parentheses go the args you're passing in the call -- if you're passing no args, then the parentheses are empty). This leaves the mere mention of any 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:-).

Below the syntax, we get into some important differences in elementary semantics -- for example, strings in Ruby are mutable objects (like in C++), while in Python they are not mutable (like in Java, or I believe C#). Again, people who judge primarily by what they're already familiar with may think this is a plus for Ruby (unless they're familiar with Java or C#, of course:-). Me, I think immutable strings are an excellent idea (and I'm not surprised that Java, independently I think, reinvented that idea which was already in Python), though I wouldn't mind having a "mutable string buffer" type as well (and ideally one with better ease-of-use than Java's own "string buffers"); and I don't give this judgment because of familiarity -- before studying Java, apart from functional programming languages where 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 does have some advantages in elementary semantics -- for example, the removal of Python's "lists vs tuples" exceedingly subtle distinction. But mostly the score (as I keep it, with simplicity a big plus and subtle, clever distinctions a notable minus) is against Ruby (eg, having both closed and half-open intervals, with the notations a..b and a...b [anybody wants to claim that it's obvious which is which?-)], is silly -- IMHO, of course!). Again, people who consider having a lot of similar but subtly different things at the core of a language a PLUS, rather than a MINUS, will of course count these "the other way around" from how I count them:-).

Don't be misled by these comparisons into thinking the two languages are very different, mind you. 他们不是。 But if I'm asked to compare "capelli d'angelo" to "spaghettini", after pointing out that these two kinds of pasta are just about undistinguishable to anybody and interchangeable in any dish you might want to prepare, I would then inevitably have to move into microscopic examination of how the lengths and diameters imperceptibly differ, how the ends of the strands are tapered in one case and not in the other, and so on -- to try and explain why I, personally, would rather have capelli d'angelo as the pasta in any kind of broth, but would prefer spaghettini as the pastasciutta to go with suitable sauces for such long thin pasta forms (olive oil, minced garlic, minced red peppers, and finely ground anchovies, for example - but if you sliced the garlic and peppers instead of mincing them, then you should choose the sounder body of spaghetti rather than the thinner evanescence of spaghettini, and would be well advised to forego the achovies and add instead some fresh spring basil [or even - - I'm a heretic...! -- light mint...] leaves -- at the very last moment before serving the dish). Ooops, sorry, it shows that I'm traveling abroad and haven't had pasta for a while, I guess. But the analogy is still pretty good!-)

So, back to Python and Ruby, we come to the two biggies (in terms of language proper -- leaving the libraries, and other important ancillaries such as tools and environments, how to embed/extend each language, etc, etc, out of it for now -- they wouldn't apply to all IMPLEMENTATIONS of each language anyway, eg, Jython vs Classic Python being two implementations of the Python language!):

  1. Ruby's iterators and codeblocks vs Python's iterators and generators;

  2. Ruby's TOTAL, unbridled "dynamicity", including the ability
    to "reopen" any existing class, including all built-in ones, and change its behavior at run-time -- vs Python's vast but bounded dynamicity, which never changes the behavior of existing built-in classes and their instances.

Personally, I consider 1 a wash (the differences are so deep that I could easily see people hating either approach and revering the other, but on MY personal scales the pluses and minuses just about even up); and 2 a crucial issue -- one that makes Ruby much more suitable for "tinkering", BUT Python equally more suitable for use in large production applications. It's funny, in a way, because both languages are so MUCH more dynamic than most others, that in the end the key difference between them from my POV should hinge on that -- that Ruby "goes to eleven" in this regard (the reference here is to "Spinal Tap", of course). In Ruby, there are no limits to my creativity -- if I decide that all string comparisons must become case-insensitive, I CAN DO THAT ! Ie, I can dynamically alter the built-in string class so that a = "Hello World" b = "hello world" if a == b print "equal!\n" else print "different!\n" end WILL print "equal". In python, there is NO way I can do that. For the purposes of metaprogramming, implementing experimental frameworks, and the like, this amazing dynamic ability of Ruby is extremely appealing. BUT -- if we're talking about large applications, developed by many people and maintained by even more, including all kinds of libraries from diverse sources, and needing to go into production in client sites... well, I don't WANT a language that is QUITE so dynamic, thank you very much. I loathe the very idea of some library unwittingly breaking other unrelated ones that rely on those strings being different -- that's the kind of deep and deeply hidden "channel", between pieces of code that LOOK separate and SHOULD BE separate, that spells death in large-scale programming. By letting any module affect the behavior of any other "covertly", the ability to mutate the semantics of built-in types is just a BAD idea for production application programming, just as it's cool for tinkering.

If I had to use Ruby for such a large application, I would try to rely on coding-style restrictions, lots of tests (to be rerun whenever ANYTHING changes -- even what should be totally unrelated...), and the like, to prohibit use of this language feature. But NOT having the feature in the first place is even better, in my opinion -- just as Python itself would be an even better language for application programming if a certain number of built-ins could be "nailed down", so I KNEW that, eg, len("ciao") is 4 (rather than having to worry subliminally about whether somebody's changed the binding of name 'len' in the builtins module...). I do hope that eventually Python does "nail down" its built-ins.

But the problem's minor, since rebinding built-ins is quite a deprecated as well as a rare practice in Python. In Ruby, it strikes me as major -- just like the too powerful macro facilities of other languages (such as, say, Dylan) present similar risks in my own opinion (I do hope that Python never gets such a powerful macro system, no matter the allure of "letting people define their own domain-specific little languages embedded in the language itself" -- it would, IMHO, impair Python's wonderful usefulness for application programming, by presenting an "attractive nuisance" to the would-be tinkerer who lurks in every programmer's heart...).

亚历克斯


Another difference in lambdas between Python and Ruby is demonstrated by Paul Graham's Accumulator Generator problem. Reprinted here:

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.

In Ruby, you can do this:

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

In Python, you'd create an object to hold the state of n:

class foo(object):
    def __init__(self, n):
        self.n = n
    def __call__(self, i):
        self.n += i
        return self.n

Some folks might prefer the explicit Python approach as being clearer conceptually, even if it's a bit more verbose. You store state like you do for anything else. You just need to wrap your head around the idea of callable objects. But regardless of which approach one prefers aesthetically, it does show one respect in which Ruby lambdas are more powerful constructs than Python's.


I would like to mention Python descriptor API that allows one customize object-to-attribute "communication". It is also noteworthy that, in Python, one is free to implement an alternative protocol via overriding the default given through the default implementation of the __getattribute__ method. Let me give more details about the aforementioned. Descriptors are regular classes with __get__ , __set__ and/or __delete__ methods. When interpreter encounters something like anObj.anAttr , the following is performed:

  • __getattribute__ method of anObj is invoked
  • __getattribute__ retrieves anAttr object from the class dict
  • it checks whether abAttr object has __get__ , __set__ or __delete__ callable objects
  • the context (ie, caller object or class, and value, instead of the latter, if we have setter) is passed to the callable object
  • the result is returned.

As was mentioned, this is the default behavior. One is free to change the protocol by re-implementing __getattribute__ .

This technique is lot more powerful than decorators.


I'm unsure of this, so I add it as an answer first.

Python treats unbound methods as functions

That means you can call a method either like theobject.themethod() or by TheClass.themethod(anobject) .

Edit: Although the difference between methods and functions is small in Python, and non-existant in Python 3, it also doesn't exist in Ruby, simply because Ruby doesn't have functions. When you define functions, you are actually defining methods on Object.

But you still can't take the method of one class and call it as a function, you would have to rebind it to the object you want to call on, which is much more obstuse.


Python has docstrings and ruby doesn't... Or if it doesn't, they are not accessible as easily as in python.

PS。 If im wrong, pretty please, leave an example? I have a workaround that i could monkeypatch into classes quite easily but i'd like to have docstring kinda of a feature in "native way".


Ruby has a line by line loop over input files (the '-n' flag) from the commandline so it can be used like AWK. This Ruby one-liner:

ruby -ne 'END {puts $.}'

will count lines like the AWK one-liner:

awk 'END{print NR}'

Ruby gets feature this through Perl, which took it from AWK as a way of getting sysadmins on board with Perl without having to change the way they do things.


Ruby has embedded documentation:

 =begin

 You could use rdoc to generate man pages from this documentation

 =end

Ruby has sigils and twigils, Python doesn't.

Edit : And one very important thing that I forgot (after all, the previous was just to flame a little bit :-p):

Python has a JIT compiler ( Psyco ), a sightly lower level language for writing faster code ( Pyrex ) and the ability to add inline C++ code ( Weave ).


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.

The standard notation makes it plain what numbers we are talking about while making the order in which to compute them ambiguous. Prefix and postfix notation make the order in which to compute plain while making the numbers ambiguous. Python would already have multiline lambdas if it were not for the difficulties caused by the syntactic whitespace. (Proposals do exist for pulling this kind of thing off without necessarily adding explicit block delimiters.)

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.

What is superficial are the aesthetic qualities of beauty that we ascribe to syntax. Aesthetics have nothing to do with how our cognition works, syntax does.


You can have code in the class definition in both Ruby and Python. However, in Ruby you have a reference to the class (self). In Python you don't have a reference to the class, as the class isn't defined yet.

一个例子:

class Kaka
  puts self
end

self in this case is the class, and this code would print out "Kaka". There is no way to print out the class name or in other ways access the class from the class definition body in Python.


从Ruby的website

相似之处与Python一样,在Ruby中,......

  • 有一个交互式提示(称为irb)。
  • 您可以在命令行上阅读文档(使用ri命令而不是pydoc)。
  • 没有特殊的行结束符(通常的换行符除外)。
  • 字符串文字可以像Python的三重引号字符串一样跨越多行。
  • 括号是用于列表的,括号是用于字典的(在Ruby中称为“哈希”)。
  • 数组的工作原理是相同的(添加它们会生成一个长数组,但像这样组成它们a3 = [ a1, a2 ]将为您提供一组数组)。
  • 对象是强类型和动态类型的。
  • 一切都是一个对象,变量只是对象的引用。
  • 尽管关键字有点不同,但例外情况也是如此。
  • 你有嵌入式文档工具(Ruby的称为rdoc)。

差异与Python不同,在Ruby中,...

  • 字符串是可变的。
  • 您可以创建常量(您不打算改变其值的变量)。
  • 有一些强制性的病例约定(例如,类名以大写字母开头,变量以小写字母开头)。
  • 只有一种列表容器(一个Array),它是可变的。
  • 双引号字符串允许使用转义序列(如\ t)和特殊的“表达式替换”语法(它允许您将Ruby表达式的结果直接插入到其他字符串中,而无需“添加”+“字符串”+“在一起”) 。 单引号字符串就像Python的r“原始字符串”。
  • 没有“新风格”和“旧风格”的课程。 只是一种。
  • 你永远不会直接访问属性。 有了Ruby,这就是所有的方法调用。
  • 方法调用的括号通常是可选的。
  • 有public,private和protected来强制访问,而不是Python的_voluntary_ underscore __convention__
  • “mixin's”被用来代替多重继承。
  • 您可以添加或修改内置类的方法。 这两种语言都可以让你在任何时候打开和修改类,但是Python可以防止修改内建函数 - Ruby不会。
  • 你有true和false而不是True和False(而不是None)。
  • 当对真相进行测试时,只有虚假和零评估为虚假值。 其他一切都是真实的(包括0,0.0,“”和[])。
  • 这是elifif而不是elif。
  • 这是需要而不是导入。 否则,使用情况是相同的。
  • 上面的行上的常用样式注释(而不是下面的文档字符串)用于生成文档。
  • 有许多捷径,虽然让你更记住,但你很快就会学习。 他们倾向于使Ruby变得有趣并且非常有效率。

在基础设施方面更多一点:

  • Python比C ++(通过像Boost.PythonSIPPy++这样的东西)要好得多,与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社区进行交互的经验。 我主要是希望能够在两者上有丰富经验的人能够放大(或拒绝)这种说法。


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

在很大程度上,区别在于语言的优雅和可读性。 要使用你提出的一个例子,理论上两者都有lambda表达式,但是Python程序员倾向于避免它们,而使用它们的结构看起来并不像Ruby中那样可读或惯用。 所以在Python中,一个好的程序员会想要采取不同的途径来解决这个问题,而不是他在Ruby中的问题,仅仅因为它实际上更好的方法。


我想提出一个原始问题的变体,“Ruby不具有Python的功能,反之亦然?” 它承认了令人失望的答案:“那么,你可以用Ruby或Python做什么,而Intercal无法做到呢?” 在那个层面上什么都没有,因为Python和Ruby都是庞大王室的一部分,坐拥图灵的近似位置。

但是这个怎么样:

在Ruby中无法用这样美观和优秀的工程来完成Python的优雅和完美的工作,反之亦然?

这可能比纯粹的功能比较更有趣。





ruby