Ruby 有哪些 Python 没有的功能,反之亦然?

2024-02-18

关于 Python 与 Ruby 的讨论有很多,我都发现它们完全没有帮助,因为它们都围绕着为什么 X 功能在 Y 语言中很糟糕,或者声称 Y 语言没有 X,尽管事实上它有。我也确切地知道为什么我更喜欢 Python,但这也是主观的,并且不会帮助任何人选择,因为他们在开发方面的品味可能与我不同。

因此,客观地列出这些差异是很有趣的。所以没有“Python 的 lambda 很糟糕”。相反,请解释 Ruby 的 lambda 可以做什么而 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

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

Ruby 具有类似 Perl 的脚本功能

Ruby 具有一流的正则表达式、$-变量、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)

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

有趣的是,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 中,您可以使用生成器模块,该模块使用延续从块创建生成器。或者,您可以只使用 block/proc/lambda!此外,在 Ruby 1.9 中,Fibers 是并且可以用作生成器,并且 Enumerator 类是一个内置生成器4 http://wiki.github.com/rdp/ruby_tutorials_core/enumerator

docs.python.org http://docs.python.org/tutorial/classes.html#generators有这个生成器示例:

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

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 在运行时从文件中检索它们使用示例 http://github.com/rdp/ri_for

Python具有多重继承

Ruby 没有(“故意”——参见 Ruby 的网站,看看这里是如何在 Ruby 中完成的 http://codeidol.com/other/rubyckbk/Modules-and-Namespaces/Simulating-Multiple-Inheritance-with-Mixins/)。它确实将模块概念重用为一种抽象类。

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 http://github.com/michaeledgar/seamless


Ruby 有以下概念blocks,本质上是一段代码周围的语法糖;它们是一种创建闭包并将它们传递给另一个可能使用或不使用该块的方法的方法。稍后可以通过以下方式调用块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 有匿名函数/闭包/lambda,但它并不完全有块,因为它缺少一些有用的语法糖。然而,至少有一种方法可以以临时的方式获得它。例如,参见here http://nicolas-lara.blogspot.com/2009/01/emulating-ruby-blocks-in-python.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ruby 有哪些 Python 没有的功能,反之亦然? 的相关文章

随机推荐

  • 如何让tomcat爆war文件

    参考tomcat 和提取的文件 https stackoverflow com questions 14945820 tomcat and extracted files 14965275 14965275我已将 server xml 配置
  • 如何查找哪个脚本修改了所选属性的css

    有没有办法获取哪些脚本修改了选定的 DOM 元素以及修改顺序的信息 在我的网站上 我修改了 div A 的宽度 但是 似乎其他一些脚本在那之后修改了该宽度 但我不知道它是哪个脚本 我怎样才能找到它 编辑 经过更多搜索后 我发现在 fireb
  • java中的自定义键盘快捷键

    I am developing a java swing application I want to add a keyboard shortcut say CTRL H This should perform the same actio
  • 在 Internet Explorer 7 中使用 z-Index 定位 div

    我有两个相对定位的 DIV A 和 B a 有一个名为 A 的 DIV 作为子元素 它是绝对定位的 z 索引为 1000 DIV B 是 DIV B 的子元素 也是绝对定位的 Firefox 按预期呈现 A B B A 从距用户最近到最远
  • Boost.MultiIndex:如何进行有效的集合交集?

    假设我们有一个data1 and data2 我怎样才能将它们与std set intersect struct pID int ID unsigned int IDf postition in the file pID int id co
  • UNIQUE 约束是否会自动在字段上创建索引?

    我是不是该定义一个单独的索引 on the email列 用于搜索目的 或者索引是 自动 添加的UNIQ EMAIL USER约束 CREATE TABLE IF NOT EXISTS customer id int 11 NOT NULL
  • 为什么我的node_modules中有@angular/core,但仍然出现此错误?

    我从 angular io 下载了一个示例项目 从这里https angular io generated zips cli quickstart cli quickstart zip https angular io generated
  • Flutter:如何更新 firestore 中数组中的数组

    消防银行 https i stack imgur com 5R9Qz png 我需要更新索引数组 0 中的状态字段 其中时间 8 00 我需要将此状态传递给 0 只是该数组位于图像中的矩阵内被视为计时器 如何通过将 status 1 字段更
  • CsvHelper - 在同一 CSV 中读取不同的记录类型

    我正在尝试从具有以下结构的 CSV 文件中读取两种类型的记录 PlaceName Longitude Latitude Elevation NameString 123 456 56 78 40 Date Count 1 1 2012 1
  • 确定一个数组是否包含在另一个数组中

    如何确定一个数组是否包含在另一个数组中 逐个元素且按顺序 我已经在 MSVS 2010 中编写了下面的程序 但不太确定如何完成确定一个数组是否出现在另一个数组中的布尔函数 void isContained int ar1 int ar2 i
  • x&&y||z 是如何计算的?

    Given int x 1 y 2 z 您能解释一下为什么结果是 x y z is 1 x y 1 x y z 1 x y z 相当于 x y z if x 1 and y 2 then x y is 1 2这是true true这是tru
  • 如何在 Neo4j Cypher 上使字符串包含过滤器

    我需要在 Neo4J 中创建一个包含过滤器的字符串 这个想法很简单 一个很好的例子是 我需要从人员数据库中检索姓名中包含汽车子字符串的所有人员 我怎样才能做到这一点 作为附加更新 从 neo4j 3 0 开始 它可能更易于使用 MATCH
  • DirectX/OpenGL 中的三角形绘制顺序

    3D API 中绘制三角形的顺序是否保证与其在索引缓冲区中的顺序相同 例如 如果我在一次绘制调用中有两个重叠的三角形 并且禁用深度测试 那么第一个或第二个三角形最终是否可见 或者我是否需要发出单独的绘制调用以确保第二个三角形出现在第一个三角
  • Zend Select 具有自连接覆盖字段

    帖子和评论存储在同一个表中 因此 为了获取每个帖子及其评论 我们这样做 posts this gt select gt setIntegrityCheck false gt from array post gt Posts array gt
  • 第一个元素偏移量

    结构的第一个元素的偏移量为 0 是否是保证 为了更准确 让我们考虑一下 struct foo int a double b struct foo ptr malloc sizeof struct foo int int ptr ptr gt
  • 您是否使用 TestInitialize 或测试类构造函数来准备每个测试?为什么?

    这个问题涉及使用 MSTest 在 Visual Studio 中进行单元测试 这很重要 因为 MSTest 的执行顺序 http blogs msdn com nnaderi archive 2007 02 17 explaining e
  • 如何修复轮询时的 Cucumber 期望错误?

    我有帮手sign in登录用户 我正在尝试使用一种新方法来确保用户使用轮询登录 def sign in user password 111111 click button sign in btn eventually 5 page shou
  • 在plsql中编写函数

    我正在查询数据库 需要解析其中一个字段以获取特定值 使用字符串函数 所以我认为最好为其编写一个函数 我以前从未在 plsql 中编写过函数 所以我决定看一些示例 我得到了一个简单的 square 函数的副本 它接受一个数字并返回它的平方 但
  • 通过 DBRef 数组查找文档

    解决方案可能就在我面前 但我还没有找到它 我的问题是我需要查找包含指定 DBRef 的所有文档 这是要搜索的集合的结构 id ObjectId 4e2d4892580fd602eb000003 date added ISODate 2011
  • Ruby 有哪些 Python 没有的功能,反之亦然?

    Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 关于 Python 与 Ruby 的讨论有很多 我都发现它们完全没有帮助 因为它们都围绕着为什