python - Ruby 有哪些 Python 没有的,反之亦然?

标签 python ruby

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








有很多关于 Python 与 Ruby 的讨论,我都认为它们完全没有帮助,因为它们都转而解释了为什么特性 X 在语言 Y 中很糟糕,或者声称语言 Y 没有 X,尽管实际上它有。我也确切地知道为什么我更喜欢 Python,但这也是主观的,并且不会帮助任何人选择,因为他们可能没有和我一样的开发品味。

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

请不要在一个答案中有几个不同之处。并投票赞成你知道正确的那些,反对那些你知道不正确(或主观)的。此外,语法上的差异并不有趣。我们知道 Python 用缩进做的事情就像 Ruby 用括号和结尾做的一样,而且 @ 在 Python 中被称为 self。

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

Ruby 在类体中有一个类引用

在 Ruby 中,您已经在类主体中引用了类(self)。在 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 拥有一流的正则表达式、$-variables、awk/perl 逐行输入循环和其他特性,使其更适合编写小型 shell 脚本,这些脚本可以处理文本文件或充当其他程序的胶水代码。

Ruby 具有一流的延续性

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

Ruby 有块

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

ruby :
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 中它会创建一个生成器。

ruby :
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 模块,该模块使用 continuation 从块创建生成器。或者,您可以只使用块/过程/lambda!此外,在 Ruby 1.9 中 Fiber 是并且可以用作生成器,并且 Enumerator 类是一个内置生成器 4

docs.python.org有这个生成器示例:
def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

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

Python 具有灵活的 namespace 处理

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

在 Python 中,该文件是一个模块,您可以使用 from themodule import * 导入其包含的名称。 ,从而如果需要的话会污染命名空间。但您也可以使用 from themodule import aname, another 仅导入选定的名称或者您可以简单地import themodule然后使用 themodule.aname 访问名称.如果你想在你的命名空间中有更多的级别,你可以拥有包,这些包是包含模块和 __init__.py 的目录。文件。

Python 有文档字符串

文档字符串是附加到模块、函数和方法的字符串,可以是
在运行时内省(introspection)。这有助于创建诸如 help 命令和
自动文档。
def frobnicate(bar):
    """frobnicate takes a bar and frobnicates it

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

Ruby 的等价物类似于 javadoc,位于方法上方而不是内部。可以使用 1.9 的 Method#source_location example use 在运行时从文件中检索它们。

Python具有多重继承

Ruby 没有(“故意”——参见 Ruby 的网站,see here how it's done in Ruby)。它确实将模块概念重用为一种抽象类。

Python 具有列表/字典推导式

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 有装饰器

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

语法差异

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

最佳答案

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,但它没有完全块,因为它缺少一些有用的语法糖。但是,至少有一种方法可以以临时方式获得它。例如,参见 here .

关于python - Ruby 有哪些 Python 没有的,反之亦然?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1113611/

相关文章:

Python Sklearn 线性回归值误差

python - 项目的 admin.py,而不是应用程序

ruby-on-rails - Sessions::CookieStore(默认)和 Sessions::CacheStore 之间有什么不同?

ruby-on-rails - 加载错误 : cannot load such file -- bundler/setup

ruby-on-rails - 无法加载此类文件 — ruby​​gems.rb

python - Jupyter Notebook - 在函数内部绘图 - 图未绘制

python - Python "open"函数是将其内容保存在内存中还是临时文件中?

python - 将电子表格的列存储在 Python 字典中

mysql - Rails 4 - 如何通过 has_many 关联与同一列上的多个条件查询集合?

Ruby % 运算符