Ruby有Python没有的,反之亦然?-Python 实用宝典

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中,您可以通过各种技术来创建延续,但是该语言没有内置支持。 红宝石有块 …
内容 隐藏

问题: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

There is a lot of discussions of Python vs Ruby, and I all find them completely unhelpful, because they all turn around why feature X sucks in language Y, or that claim language Y doesn't have X, although in fact it does. I also know exactly why I prefer Python, but that's also subjective, and wouldn't help anybody choosing, as they might not have the same tastes in development as I do.

It would therefore be interesting to list the differences, objectively. So no "Python's lambdas sucks". Instead explain what Ruby's lambdas can do that Python's can't. No subjectivity. Example code is good!

Don't have several differences in one answer, please. And vote up the ones you know are correct, and down those you know are incorrect (or are subjective). Also, differences in syntax is not interesting. We know Python does with indentation what Ruby does with brackets and ends, and that @ is called self in Python.

UPDATE: This is now a community wiki, so we can add the big differences here.

Ruby has a class reference in the class body

In Ruby you have a reference to the class (self) already in the class body. In Python you don't have a reference to the class until after the class construction is finished.

An example:

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 (outside method definitions).

All classes are mutable in Ruby

This lets you develop extensions to core classes. Here's an example of a rails extension:

class String
  def starts_with?(other)
    head = self[0, other.length]
    head == other
  end
end

Python (imagine there were no ''.startswith method):

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

You could use it on any sequence (not just strings). In order to use it you should import it explicitly e.g., from some_module import starts_with.

Ruby has Perl-like scripting features

Ruby has first class regexps, $-variables, the awk/perl line by line input loop and other features that make it more suited to writing small shell scripts that munge text files or act as glue code for other programs.

Ruby has first class continuations

Thanks to the callcc statement. In Python you can create continuations by various techniques, but there is no support built in to the language.

Ruby has blocks

With the "do" statement you can create a multi-line anonymous function in Ruby, which will be passed in as an argument into the method in front of do, and called from there. In Python you would instead do this either by passing a method or with generators.

Ruby:

amethod { |here|
    many=lines+of+code
    goes(here)
}

Python (Ruby blocks correspond to different constructs in Python):

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

Or

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

Or

def function(here):
    many=lines+of+code
    goes(here)

amethod(function)     # `function` is a callback

Interestingly, the convenience statement in Ruby for calling a block is called "yield", which in Python will create a generator.

Ruby:

def themethod
    yield 5
end

themethod do |foo|
    puts foo
end

Python:

def themethod():
    yield 5

for foo in themethod():
    print foo

Although the principles are different, the result is strikingly similar.

Ruby supports functional style (pipe-like) programming more easily

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

Python:

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

Python has built-in generators (which are used like Ruby blocks, as noted above)

Python has support for generators in the language. In Ruby 1.8 you can use the generator module which uses continuations to create a generator from a block. Or, you could just use a block/proc/lambda! Moreover, in Ruby 1.9 Fibers are, and can be used as, generators, and the Enumerator class is a built-in generator 4

docs.python.org has this generator example:

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

Contrast this with the above block examples.

Python has flexible name space handling

In Ruby, when you import a file with require, all the things defined in that file will end up in your global namespace. This causes namespace pollution. The solution to that is Rubys modules. But if you create a namespace with a module, then you have to use that namespace to access the contained classes.

In Python, the file is a module, and you can import its contained names with from themodule import *, thereby polluting the namespace if you want. But you can also import just selected names with from themodule import aname, another or you can simply import themodule and then access the names with themodule.aname. If you want more levels in your namespace you can have packages, which are directories with modules and an __init__.py file.

Python has docstrings

Docstrings are strings that are attached to modules, functions and methods and can be introspected at runtime. This helps for creating such things as the help command and automatic documentation.

def frobnicate(bar):
    """frobnicate takes a bar and frobnicates it

       >>> bar = Bar()
       >>> bar.is_frobnicated()
       False
       >>> frobnicate(bar)
       >>> bar.is_frobnicated()
       True
    """

Ruby's equivalent are similar to javadocs, and located above the method instead of within it. They can be retrieved at runtime from the files by using 1.9's Method#source_location example use

Python has multiple inheritance

Ruby does not ("on purpose" -- see Ruby's website, see here how it's done in Ruby). It does reuse the module concept as a type of abstract classes.

Python has list/dict comprehensions

Python:

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

Ruby:

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]

Ruby:

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'}

Ruby:

>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}

Python has decorators

Things similar to decorators can also be created in Ruby, and it can also be argued that they aren't as necessary as in Python.

Syntax differences

Ruby requires "end" or "}" to close all of its scopes, while Python uses white-space only. There have been recent attempts in Ruby to allow for whitespace only indentation 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,但由于缺少一些有用的语法糖,因此它没有块。但是,至少有一种方法可以临时获得它。例如,请参阅此处

Ruby has the concepts of blocks, which are essentially syntactic sugar around a section of code; they are a way to create closures and pass them to another method which may or may not use the block. A block can be invoked later on through a yield statement.

For example, a simple definition of an each method on Array might be something like:

class Array
  def each
    for i in self  
      yield(i)     # If a block has been passed, control will be passed here.
    end  
  end  
end  

Then you can invoke this like so:

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

Python has anonymous functions/closures/lambdas, but it doesn't quite have blocks since it's missing some of the useful syntactic sugar. However, there's at least one way to get it in an ad-hoc fashion. See, for example, here.


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

Python Example

Functions are first-class variables in Python. You can declare a function, pass it around as an object, and overwrite it:

def func(): print "hello"
def another_func(f): f()
another_func(func)

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

This is a fundamental feature of modern scripting languages. JavaScript and Lua do this, too. Ruby doesn't treat functions this way; naming a function calls it.

Of course, there are ways to do these things in Ruby, but they're not first-class operations. For example, you can wrap a function with Proc.new to treat it as a variable--but then it's no longer a function; it's an object with a "call" method.

Ruby's functions aren't first-class objects

Ruby functions aren't first-class objects. Functions must be wrapped in an object to pass them around; the resulting object can't be treated like a function. Functions can't be assigned in a first-class manner; instead, a function in its container object must be called to modify them.

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"

在考虑如何做时,请执行以下操作:

  1. 把句子分成单词
  2. 反转字
  3. 重新将单词重新组合成字符串

在Ruby中,您可以这样做:

sentence.split.reverse.join ' '

正如您所想的那样,以相同的顺序依次调用一个方法。

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

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

这不难理解,但流程不尽相同。主题(句子)埋在中间。这些操作是功能和对象方法的混合。这是一个简单的示例,但是在真正使用和理解Ruby时,尤其是在非琐碎的任务上,人们发现了许多不同的示例。

Ultimately all answers are going to be subjective at some level, and the answers posted so far pretty much prove that you can't point to any one feature that isn't doable in the other language in an equally nice (if not similar) way, since both languages are very concise and expressive.

I like Python's syntax. However, you have to dig a bit deeper than syntax to find the true beauty of Ruby. There is zenlike beauty in Ruby's consistency. While no trivial example can possibly explain this completely, I'll try to come up with one here just to explain what I mean.

Reverse the words in this string:

sentence = "backwards is sentence This"

When you think about how you would do it, you'd do the following:

  1. Split the sentence up into words
  2. Reverse the words
  3. Re-join the words back into a string

In Ruby, you'd do this:

sentence.split.reverse.join ' '

Exactly as you think about it, in the same sequence, one method call after another.

In python, it would look more like this:

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

It's not hard to understand, but it doesn't quite have the same flow. The subject (sentence) is buried in the middle. The operations are a mix of functions and object methods. This is a trivial example, but one discovers many different examples when really working with and understanding Ruby, especially on non-trivial tasks.


回答 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

Python has a "we're all adults here" mentality. Thus, you'll find that Ruby has things like constants while Python doesn't (although Ruby's constants only raise a warning). The Python way of thinking is that if you want to make something constant, you should put the variable names in all caps and not change it.

For example, 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

您会看到method1method2都已添加到您的命名空间中。您不能仅导入method1。您要么同时导入它们,要么根本不导入它们。在Python中,您只能导入您选择的方法。如果有这个名字,也许会叫做选择性导入?

You can import only specific functions from a module in Python. In Ruby, you import the whole list of methods. You could "unimport" them in Ruby, but it's not what it's all about.

EDIT:

let's take this Ruby module :


module Whatever
  def method1
  end

  def method2
  end
end

if you include it in your code :


include Whatever

you'll see that both method1 and method2 have been added to your namespace. You can't import only method1. You either import them both or you don't import them at all. In Python you can import only the methods of your choosing. If this would have a name maybe it would be called selective importing?


回答 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变得有趣且非常有生产力。

From Ruby's website:

Similarities As with Python, in 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).

Differences Unlike Python, in 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.

回答 6

Ruby比Python具有的脚本语言功能。在这种情况下,脚本语言意味着用于Shell脚本和常规文本操作中的“胶水代码”。

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

连同其简洁而优美的语法,它非常适合此类任务。

对我而言,Python更像是一种动态类型化的业务语言,它非常易于学习并且语法简洁。不像Ruby那样“酷”,但很简洁。Python对Ruby而言,对我来说,是其他库的大量绑定。绑定到Qt和其他GUI库,许多游戏支持库以及和和。Ruby少得多。尽管经常使用的绑定(例如与数据库的绑定)具有良好的质量,但我发现利基库在Python中得到了更好的支持,即使对于同一库也有Ruby绑定。

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

What Ruby has over Python are its scripting language capabilities. Scripting language in this context meaning to be used for "glue code" in shell scripts and general text manipulation.

These are mostly shared with Perl. First-class built-in regular expressions, $-Variables, useful command line options like Perl (-a, -e) etc.

Together with its terse yet epxressive syntax it is perfect for these kind of tasks.

Python to me is more of a dynamically typed business language that is very easy to learn and has a neat syntax. Not as "cool" as Ruby but neat. What Python has over Ruby to me is the vast number of bindings for other libs. Bindings to Qt and other GUI libs, many game support libraries and and and. Ruby has much less. While much used bindings e.g. to Databases are of good quality I found niche libs to be better supported in Python even if for the same library there is also a Ruby binding.

So, I'd say both languages have its use and it is the task that defines which one to use. Both are easy enough to learn. I use them side-by-side. Ruby for scripting and Python for stand-alone apps.


回答 7

我不认为“ Ruby具有X而Python没有,而Python具有Y而Ruby没有”是查看它的最有用的方法。它们是非常相似的语言,具有许多共享功能。

在很大程度上,区别在于该语言使语言更加优雅和可读。使用您提出的示例,理论上两者都具有lambda,但是Python程序员倾向于避免使用lambda,并且使用它们构造的构造看起来不像Ruby那样易读或惯用。因此,在Python中,优秀的程序员将希望采用与Ruby中不同的方法来解决问题,只是因为这实际上解决问题的更好方法。

I don't think "Ruby has X and Python doesn't, while Python has Y and Ruby doesn't" is the most useful way to look at it. They're quite similar languages, with many shared abilities.

To a large degree, the difference is what the language makes elegant and readable. To use an example you brought up, both do theoretically have lambdas, but Python programmers tend to avoid them, and constructs made using them do not look anywhere near as readable or idiomatic as in Ruby. So in Python, a good programmer will want to take a different route to solving the problem than he would in Ruby, just because it actually is the better way to do it.


回答 8

我想提出一个原始问题的变体:“ Ruby有哪些Python没有的,反之亦然?” 它承认了令人失望的答案:“那么,用Intercal无法做到的Ruby或Python可以做什么?” 在这个级别上什么都没有,因为Python和Ruby都是庞大的皇室家族的一部分,坐在图灵近似的宝座上。

但是呢:

在Python中,优雅而良好的工作可以做得很好,而在Ruby中却不能做到如此美丽和出色的工程,反之亦然?

这可能比单纯的功能比较有趣。

I'd like to suggest a variant of the original question, "What does Ruby have that Python doesn't, and vice versa?" which admits the disappointing answer, "Well, what can you do with either Ruby or Python that can't be done in Intercal?" Nothing on that level, because Python and Ruby are both part of the vast royal family sitting on the throne of being Turing approximant.

But what about this:

What can be done gracefully and well in Python that can't be done in Ruby with such beauty and good engineering, or vice versa?

That may be much more interesting than mere feature comparison.


回答 9

Python具有用于列表推导和生成器的显式内置语法,而在Ruby中,您将使用映射和代码块。

比较

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

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

Python has an explicit, builtin syntax for list-comprehenions and generators whereas in Ruby you would use map and code blocks.

Compare

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

to

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

回答 10

“以大写字母开头的变量将成为常量,无法修改”

错误。他们能。

您只会收到警告。

"Variables that start with a capital letter becomes constants and can't be modified"

Wrong. They can.

You only get a warning if you do.


回答 11

基础设施方面:

  • 与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社区进行交互的丰富经验。我主要是为了补充这一点,希望对两者都有丰富经验的人可以放大(或拒绝)此声明。

Somewhat more on the infrastructure side:

  • Python has much better integration with C++ (via things like Boost.Python, SIP, and Py++) than Ruby, where the options seem to be either write directly against the Ruby interpreter API (which you can do with Python as well, of course, but in both cases doing so is low level, tedious, and error prone) or use SWIG (which, while it works and definitely is great if you want to support many languages, isn't nearly as nice as Boost.Python or SIP if you are specifically looking to bind C++).

  • Python has a number of web application environments (Django, Pylons/Turbogears, web.py, probably at least half a dozen others), whereas Ruby (effectively) has one: Rails. (Other Ruby web frameworks do exist, but seemingly have a hard time getting much traction against Rails). Is this aspect good or bad? Hard to say, and probably quite subjective; I can easily imagine arguments that the Python situation is better and that the Ruby situation is better.

  • Culturally, the Python and Ruby communities seem somewhat different, but I can only hint at this as I don't have that much experience interacting with the Ruby community. I'm adding this mostly in the hopes that someone who has a lot of experience with both can amplify (or reject) this statement.


回答 12

无耻地复制/粘贴自:Alex Martellicomp.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语言的两种实现!):

  1. Ruby的迭代器和代码块与Python的迭代器和生成器;

  2. 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对应用程序编程的出色用处。潜伏在每个程序员的心中...)。

亚历克斯

Shamelessly copy/pasted from: Alex Martelli answer on "What's better about Ruby than Python" thread from comp.lang.python mailing list.

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

"Brandon J. Van Every" wrote:

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

Wouldn't it make much more sense to ask Ruby people this, rather than Python people?

Might, or might not, depending on one's purposes -- for example, if one's purposes include a "sociological study" of the Python community, then putting questions to that community is likely to prove more revealing of information about it, than putting them elsewhere:-).

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).

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 (e.g., 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. They aren't. 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, e.g., 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! I.e., 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 d-e-a-t-h 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, e.g., 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...).

Alex


回答 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

Some others from:

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

(If I have misintrepreted anything or any of these have changed on the Ruby side since that page was updated, someone feel free to edit...)

Strings are mutable in Ruby, not in Python (where new strings are created by "changes").

Ruby has some enforced case conventions, Python does not.

Python has both lists and tuples (immutable lists). Ruby has arrays corresponding to Python lists, but no immutable variant of them.

In Python, you can directly access object attributes. In Ruby, it's always via methods.

In Ruby, parentheses for method calls are usually optional, but not in Python.

Ruby has public, private, and protected to enforce access, instead of Python’s convention of using underscores and name mangling.

Python has multiple inheritance. Ruby has "mixins."

And another very relevant link:

http://c2.com/cgi/wiki?PythonVsRuby

Which, in particular, links to another good one by Alex Martelli, who's been also posting a lot of great stuff here on SO:

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


回答 14

我不确定,因此我首先将其添加为答案。

Python将未绑定方法视为函数

这意味着您可以通过theobject.themethod()或调用方法TheClass.themethod(anobject)

编辑:尽管方法和函数之间的差异在Python中很小,在Python 3中不存在,但是在Ruby中也不存在,仅因为Ruby没有函数。定义函数时,实际上是在Object上定义方法。

但是您仍然不能采用一个类的方法并将其作为函数调用,您将不得不将其重新绑定到要调用的对象上,这更加令人费解。

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.


回答 15

我想提到Python描述符API,该API允许一个自定义对象到属性的“通信”。还值得注意的是,在Python中,可以通过覆盖通过方法的默认实现提供的默认值来自由实现另一种协议__getattribute__。让我提供有关上述内容的更多详细信息。描述是在普通类__get____set__和/或__delete__方法。当解释器遇到类似的内容时anObj.anAttr,将执行以下操作:

  • __getattribute__的方法anObj被调用
  • __getattribute__ 从类字典中检索anAttr对象
  • 它检查abAttr对象是否具有__get____set____delete__可调用对象
  • 上下文(即调用方对象或类,以及值,而不是后者,如果有设置器的话)被传递给可调用对象
  • 返回结果。

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

该技术比装饰器功能强大得多。

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 (i.e., 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.


回答 16

Ruby使用内置了延续支持callcc

因此,您可以实施酷的东西,例如amb-operator

Ruby has builtin continuation support using callcc.

Hence you can implement cool things like the amb-operator


回答 17

在此阶段,Python仍具有更好的unicode支持

At this stage, Python still has better unicode support


回答 18

Python具有文档字符串,而ruby没有...或者,如果没有,则无法像在python中那样容易地访问它们。

附言 如果我错了,请留下一个例子?我有一个解决方法,可以很容易地将其Monkey类拼凑到类中,但是我想以“本机方式”使用文档字符串有点功能。

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


回答 19

Ruby在命令行中逐行循环输入文件('-n'标志),因此可以像AWK一样使用。这个Ruby一线:

ruby -ne 'END {puts $.}'

将计数像AWK一线式的行:

awk 'END{print NR}'

Ruby通过Perl获得了此功能,Perl从AWK那里获得了它,这是使系统管理员可以使用Perl的一种方式,而不必更改他们的工作方式。

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.


回答 20

Ruby有Sigils和Twigils,Python没有。

编辑:这是我忘记的一个非常重要的事情(毕竟,前一个只是发火了一点:-p):

Python具有JIT编译器(Psyco),一种用于编写更快的代码的低级语言(Pyrex)和添加内联C ++代码(Weave)的能力。

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).


回答 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实用程序员指南》

My python's rusty, so some of these may be in python and i just don't remember/never learned in the first place, but here are the first few that I thought of:

Whitespace

Ruby handles whitespace completely different. For starters, you don't need to indent anything (which means it doesn't matter if you use 4 spaces or 1 tab). It also does smart line continuation, so the following is valid:

def foo(bar,
        cow)

Basically, if you end with an operator, it figures out what is going on.

Mixins

Ruby has mixins which can extend instances instead of full classes:

module Humor
  def tickle
    "hee, hee!"
  end
end
a = "Grouchy"
a.extend Humor
a.tickle    »   "hee, hee!"

Enums

I'm not sure if this is the same as generators, but as of Ruby 1.9 ruby as enums, so

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

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

"Keyword Arguments"

Both of the items listed there are supported in Ruby, although you can't skip default values like that. You can either go in order

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

Note that c=5 actually assigns the variable c in the calling scope the value 5, and sets the parameter b the value 5.

or you can do it with hashes, which address the second issue

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

Reference: The Pragmatic Progammer's Guide to Ruby


回答 22

您可以在Ruby和Python的类定义中都包含代码。但是,在Ruby中,您有对类(自身)的引用。在Python中,您没有对该类的引用,因为该类尚未定义。

一个例子:

class Kaka
  puts self
end

在这种情况下,self是类,并且此代码将打印出“ Kaka”。无法打印出类名,也无法通过其他方式从Python中的类定义主体访问该类。

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.

An example:

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.


回答 23

语法不是一件小事,它直接影响我们的思维方式。它也直接影响我们为使用的系统创建的规则。例如,由于我们编写数学方程式或句子的方式,我们具有运算顺序。数学的标准表示法允许人们以多种方式阅读它,并在给定相同方程的情况下得出不同的答案。如果我们使用前缀或后缀表示法,那么我们将创建规则以区分要操纵的数字,而不是仅具有计算值顺序的规则。

标准表示法清楚地表明了我们在谈论什么数字,同时使它们的计算顺序不明确。前缀和后缀表示法在使数字含糊不清的同时,使计算明文的顺序变得容易。如果不是因为语法空白引起的困难,Python就已经有了多行lambda。(确实存在一些建议,无需添加显式的块定界符就可以拉出此类内容。)

我发现在条件为的情况下编写条件(如果条件为假)要比在Ruby或其他语言中用语义上等效的“ if-not”构造容易得多,而用Ruby语句中的else语句更容易编写条件。如果当今人们使用的大多数语言的力量相等,那么如何将每种语言的语法视为琐碎的事情呢?在诸如块和继承机制等特定功能之后,语法是语言最重要的部分,这并不是肤浅的事情。

肤浅的是我们赋予句法的美的美学特质。美学与我们的认知如何运作,语法无关。

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.


回答 24

惊讶地发现红宝石的“方法缺失”机制一无所获。我将提供Rails中find_by _...方法的示例,作为该语言功能强大功能的示例。我的猜测是可以在Python中实现类似的功能,但据我所知它本身并不存在。

Surprised to see nothing mentioned of ruby's "method missing" mechanism. I'd give examples of the find_by_... methods in Rails, as an example of the power of that language feature. My guess is that something similar could be implemented in Python, but to my knowledge it isn't there natively.


回答 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更强大。

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.


回答 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是始终附加的影响。

python has named optional arguments

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 has only positioned arguments because b=2 in the function declaration is an affectation that always append.


回答 27

Ruby嵌入了文档:

 =begin

 You could use rdoc to generate man pages from this documentation

 =end

Ruby has embedded documentation:

 =begin

 You could use rdoc to generate man pages from this documentation

 =end

回答 28


回答 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”

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

With Cargo you can "require libraries without cluttering your namespace".

# 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实用宝典 发表,其版权均为 Python 实用宝典 所有,文章内容系作者个人观点,不代表 Python 实用宝典 对观点赞同或支持。如需转载,请注明文章来源。
1

抱歉,评论已关闭!