Ruby 有什麼 Python 沒有的,反之亦然?

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

有很多關於 Python 與 Ruby 的討論,我都覺得它們完全沒有幫助,因為他們都轉過身來為什麼功能 X 在語言 Y 中很糟糕,或者聲稱語言 Y 沒有 X,儘管事實上它確實。我也確切地知道為什麼我更喜歡 Python,但這也是主觀的,並且不會幫助任何人選擇,因為他們在開發方面的品味可能與我不同。

因此客觀地列出差異會很有趣。所以沒有“Python”的 lambdas 很爛”。而是解釋一下 Ruby 的 lambda 可以做什麼,而 Python 不能。沒有主觀性。示例代碼很好!

請不要在一個答案中有幾個不同之處。對你知道是正確的投贊成票,對你知道不正確(或主觀的)投反對票。此外,語法上的差異並不有趣。我們知道 Python 處理縮進就像 Ruby 處理括號和結尾一樣,並且 @ 在 Python 中稱為 self。

更新:現在這是一個社區 wiki,因此我們可以在此處添加重大差異。

p>

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 具有一流的正則表達式、$ 變量、awk/perl 逐行輸入循環和其他特性,使其更適合編寫小型 shell 腳本來處理文本文件或充當其他程序的膠水代碼。

Ruby 有一流的延續

感謝 callcc 語句。在 Python 中,您可以通過各種技術創建延續,但該語言沒有內置支持。

Ruby 有塊

使用“do”語句,您可以創建多Ruby 中的 line 匿名函數,它將作為參數傳入 do 前面的方法中,並從那裡調用。在 Python 中,您可以通過傳遞方法或生成器來實現。

Ruby:

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

Python(Ruby 塊對應 Python 中的不同結構):

with amethod() as here: # `amethod() 是一個上下文管理器 many=lines+of+code go(here) 

或者

for here in amethod() : # `amethod()` 是一個可迭代的 many=lines+of+code go(here) 

Or

def function(here): many =lines+of+code go(here) amethod(function) # `function` 是一個回調 

有趣的是,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(" ") 

Python:

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

Python 有內置的生成器(就像上面提到的 Ruby 塊一樣使用)

Python 支持該語言的生成器。在 Ruby 1.8 中,您可以使用生成器模塊,該模塊使用延續從塊中創建生成器。或者,您可以只使用塊/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 然後使用 themodule.aname。如果你想在你的命名空間中有更多級別,你可以有包,它們是帶有模塊的目錄和一個 __init__.py 文件。

Python 有文檔字符串

文檔字符串是附加到模塊、函數和方法的字符串,可以在運行時進行自省。這有助於創建諸如幫助命令和自動文檔之類的東西。

def frobnicate(bar): """frobnicate 接受一個 bar 並對其進行 frobnicates >>> bar = Bar( ) >>> bar.is_frobnicated() False >>> frobnicate(bar) >>> bar.is_frobnicated() True """ 

Ruby "s 等價物類似於 javadocs,並且位於方法上方而不是其中。可以在運行時使用 1.9"s Method#source_location example use

Python 有多重繼承

Ruby 沒有(“故意”——見Ruby 的網站,看這裡"在 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)) <生成器對象<genexpr>在 0xb7c1ccd4> >>> list(_) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Ruby:

p =進程 { |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:

>>哈希[{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/無縫