Ruby 有哪些 Python 没有的,反之亦然? [英] What does Ruby have that Python doesn't, and vice versa?

查看:40
本文介绍了Ruby 有哪些 Python 没有的,反之亦然?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

Ruby 在类体中有一个类引用

在 Ruby 中,您已经在类主体中引用了类(self).在 Python 中,在类构建完成之前,您没有对类的引用.

示例:

类卡卡把自己结尾

self 在这种情况下是类,这段代码会打印出Kaka".无法打印出类名或以其他方式从 Python 中的类定义体(方法定义之外)访问类.

Ruby 中的所有类都是可变的

这让您可以开发核心类的扩展.下面是一个 rails 扩展的例子:

class 字符串def starts_with?(other)head = self[0, other.length]头 == 其他结尾结尾

Python(假设没有 ''.startswith 方法):

def starts_with(s, prefix):返回 s[:len(prefix)] == 前缀

您可以在任何序列(不仅仅是字符串)上使用它.为了使用它,你应该明确地导入它,例如,from some_module import starts_with.

Ruby 具有类似 Perl 的脚本功能

Ruby 具有一流的正则表达式、$-variables、awk/perl 逐行输入循环和其他特性,使其更适合编写小型 shell 脚本,这些脚本可以处理文本文件或充当其他程序的胶水代码.

>

Ruby 具有一流的延续性

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

Ruby 有块

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

红宝石:

方法{ |这里|许多=行+行+代码去(这里)}

Python(Ruby 块对应于 Python 中的不同结构):

with amethod() as here: # `amethod() 是一个上下文管理器许多=行+行+代码去(这里)

for here in amethod(): # `amethod()` 是一个可迭代的许多=行+行+代码去(这里)

def 函数(这里):许多=行+行+代码去(这里)amethod(function) # `function` 是一个回调

有趣的是,Ruby 中用于调用块的便捷语句称为yield",在 Python 中它将创建一个生成器.

红宝石:

def 方法产量 5结尾方法做 |foo|把 foo结尾

蟒蛇:

def themethod():产量 5对于 themethod() 中的 foo:打印 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 中,您可以使用 generator 模块,该模块使用 continuation 从块创建生成器.或者,您可以只使用块/过程/lambda!此外,在 Ruby 1.9 中 Fiber 是并且可以用作生成器,并且 Enumerator 类是一个内置生成器 4

docs.python.org 有这个生成器示例:

def reverse(data):对于范围内的索引(len(data)-1, -1, -1):产量数据[索引]

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

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 拿了一个酒吧并 frobnicate 它>>>酒吧 = 酒吧()>>>bar.is_frobnicated()错误的>>>frobnicate(酒吧)>>>bar.is_frobnicated()真的"""

Ruby 的等价物类似于 javadoc,并且位于方法上方而不是内部.它们可以在运行时通过使用 1.9 的 Method#source_location example use

Python 具有多重继承

Ruby 没有(故意"——参见 Ruby 的网站,在这里查看它是如何在 Ruby 中完成的).它确实将模块概念重用为一种抽象类.

Python 具有列表/字典推导式

蟒蛇:

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

红宝石:

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

蟒蛇:

<预><代码>>>>(x*x 代表范围内的 x(10))<生成器对象<genexpr>在 0xb7c1ccd4>>>>列表(_)[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'}

红宝石:

<代码>>>哈希[{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 和 Python 中的类定义中包含代码.但是,在 Ruby 中,您可以引用类(self).在 Python 中,您没有对该类的引用,因为该类尚未定义.

示例:

类卡卡把自己结尾

self 在这种情况下是类,这段代码会打印出Kaka".没有办法打印出类名或以其他方式从 Python 中的类定义体访问该类.

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

解决方案

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.

这篇关于Ruby 有哪些 Python 没有的,反之亦然?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆