มีการพูดคุยกันมากมายเกี่ยวกับ Python กับ Ruby และฉันทุกคนพบว่าพวกเขาไม่ช่วยเหลืออย่างสมบูรณ์เพราะพวกเขาทุกคนหันมามองว่าทำไมคุณลักษณะ X ดูดในภาษา Y หรือภาษาที่อ้างว่า Y ไม่มี X ถึงแม้ว่าในความเป็นจริงแล้ว ฉันรู้เหมือนกันว่าทำไมฉันถึงชอบ Python แต่มันก็เป็นอัตนัยและไม่ช่วยใครเลือกเพราะอาจไม่มีรสนิยมในการพัฒนาเหมือนฉัน
ดังนั้นจึงน่าสนใจที่จะแสดงรายการความแตกต่างอย่างเป็นกลาง ดังนั้นจึงไม่มี "ลูกแกะของงูหลามดูด" แทนที่จะอธิบายว่า lambdas ของ Ruby สามารถทำอะไรได้บ้างที่ Python ทำไม่ได้ ไม่มีตัวตน โค้ดตัวอย่างดี!
กรุณามีความแตกต่างหลายอย่างในหนึ่งคำตอบโปรด และโหวตคนที่คุณรู้ว่าถูกต้องและคนที่คุณรู้ว่าไม่ถูกต้อง นอกจากนี้ความแตกต่างในไวยากรณ์ไม่น่าสนใจ เรารู้ว่า Python ทำด้วยการเยื้องสิ่งที่ Ruby ทำกับวงเล็บใหญ่และส่วนท้ายและ @ นั้นเรียกว่า self in Python
UPDATE: ตอนนี้เป็นวิกิชุมชนแล้วเราจึงสามารถเพิ่มความแตกต่างใหญ่ ๆ ได้ที่นี่
Ruby มีการอ้างอิงคลาสในเนื้อหาคลาส
ใน Ruby คุณมีการอ้างอิงถึงคลาส (ตัวเอง) แล้วในเนื้อหาของคลาส ใน Python คุณไม่มีการอ้างอิงถึงคลาสจนกว่าจะเสร็จสิ้นการสร้างคลาส
ตัวอย่าง:
class Kaka
puts self
end
ตนเองในกรณีนี้คือคลาสและรหัสนี้จะพิมพ์ "Kaka" ไม่มีวิธีพิมพ์ชื่อคลาสหรือวิธีอื่นเข้าถึงคลาสจากเนื้อหานิยามคลาสใน Python (นิยามเมธอดภายนอก)
คลาสทั้งหมดไม่แน่นอนใน Ruby
สิ่งนี้ช่วยให้คุณพัฒนาส่วนขยายไปยังคลาสหลัก นี่คือตัวอย่างของการขยายราง:
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 มี regexps ชั้นหนึ่ง, $ -variables, บรรทัด awk / perl โดย line input loop และคุณสมบัติอื่น ๆ ที่ทำให้เหมาะกับการเขียนเชลล์สคริปต์ขนาดเล็กที่ทำให้ไฟล์ข้อความหรือทำหน้าที่เป็นรหัสกาวสำหรับโปรแกรมอื่น ๆ
ทับทิมมีความต่อเนื่องชั้นหนึ่ง
ขอบคุณคำสั่ง 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
งูหลาม:
def themethod():
yield 5
for foo in themethod():
print 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 คุณสามารถใช้โมดูลเครื่องกำเนิดไฟฟ้าซึ่งใช้การดำเนินการต่อเพื่อสร้างเครื่องกำเนิดไฟฟ้าจากบล็อก หรือคุณสามารถใช้บล็อก / 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
ทุกสิ่งที่กำหนดไว้ในไฟล์นั้นจะสิ้นสุดในเนมสเปซส่วนกลางของคุณ สิ่งนี้ทำให้เกิดมลภาวะในเนมสเปซ วิธีแก้ปัญหานั่นคือโมดูลรูบี้ แต่ถ้าคุณสร้างเนมสเปซด้วยโมดูลคุณต้องใช้เนมสเปซนั้นเพื่อเข้าถึงคลาสที่มีอยู่
ใน Python ไฟล์เป็นโมดูลและคุณสามารถนำเข้าชื่อที่มีอยู่ด้วยfrom themodule import *
ซึ่งจะทำให้เนมสเปซสกปรกหากคุณต้องการ แต่คุณยังสามารถนำเข้าเฉพาะชื่อที่เลือกด้วยfrom themodule import aname, another
หรือคุณสามารถimport themodule
เข้าถึงชื่อthemodule.aname
ได้อย่างง่ายดาย หากคุณต้องการระดับเพิ่มเติมในเนมสเปซของคุณคุณสามารถมีแพ็คเกจซึ่งเป็นไดเรกทอรีที่มีโมดูลและ__init__.py
ไฟล์
Python มีเอกสารประกอบ
Docstrings เป็นสตริงที่เชื่อมต่อกับโมดูลฟังก์ชั่นและวิธีการและสามารถตรวจสอบได้ในขณะทำงาน สิ่งนี้จะช่วยในการสร้างสิ่งต่าง ๆ เช่นคำสั่งช่วยเหลือและเอกสารอัตโนมัติ
def frobnicate(bar):
"""frobnicate takes a bar and frobnicates it
>>> bar = Bar()
>>> bar.is_frobnicated()
False
>>> frobnicate(bar)
>>> bar.is_frobnicated()
True
"""
รูบี้เทียบเท่าของ javadocs และอยู่เหนือวิธีแทนที่จะอยู่ข้างใน พวกเขาสามารถดึงข้อมูลได้จากรันไทม์จากไฟล์โดยใช้การใช้ตัวอย่าง # method_ source_location
Python มีหลายมรดก
Ruby ไม่ ("กับจุดประสงค์" - ดูเว็บไซต์ของ Ruby ดูที่นี่ทำอย่างไรใน Ruby ) มันนำแนวคิดของโมดูลมาใช้ใหม่เป็นคลาสนามธรรม
Python มี list / dict comprehensions
งูหลาม:
res = [x*x for x in range(1, 10)]
ทับทิม:
res = (0..9).map { |x| x * x }
งูหลาม:
>>> (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 ใช้ white-space เท่านั้น ทับทิมมีความพยายามครั้งล่าสุดในการอนุญาตให้เว้นวรรคเยื้องเท่านั้นhttp://github.com/michaeledgar/se ราบรื่น