Ada banyak diskusi tentang Python vs Ruby, dan saya semua menganggapnya sama sekali tidak membantu, karena mereka semua berbalik mengapa fitur X menyebalkan dalam bahasa Y, atau bahwa bahasa klaim Y tidak memiliki X, meskipun kenyataannya memang demikian. Saya juga tahu persis mengapa saya lebih suka Python, tetapi itu juga subjektif, dan tidak akan membantu siapa pun memilih, karena mereka mungkin tidak memiliki selera yang sama dalam pengembangan seperti saya.
Oleh karena itu, akan menarik untuk membuat daftar perbedaan secara obyektif. Jadi tidak ada "lambda Python menyebalkan". Alih-alih jelaskan apa yang lambda Ruby bisa lakukan yang tidak bisa dilakukan Python. Tidak ada subjektivitas. Kode contoh itu bagus!
Jangan memiliki beberapa perbedaan dalam satu jawaban. Dan pilih yang Anda tahu benar, dan turunkan yang Anda tahu salah (atau subjektif). Selain itu, perbedaan sintaksis juga tidak menarik. Kita tahu Python melakukan indentasi seperti yang dilakukan Ruby dengan tanda kurung dan ujung, dan @ disebut self dalam Python.
PEMBARUAN: Sekarang ini adalah wiki komunitas, jadi kami dapat menambahkan perbedaan besar di sini.
Ruby memiliki referensi kelas di badan kelas
Di Ruby Anda memiliki referensi ke kelas (diri) yang sudah ada di badan kelas. Dengan Python, Anda tidak memiliki referensi ke kelas sampai konstruksi kelas selesai.
Sebuah contoh:
class Kaka
puts self
end
self dalam hal ini adalah kelas, dan kode ini akan mencetak "Kaka". Tidak ada cara untuk mencetak nama kelas atau dengan cara lain mengakses kelas dari badan definisi kelas dengan Python (definisi metode luar).
Semua kelas bisa berubah di Ruby
Ini memungkinkan Anda mengembangkan ekstensi ke kelas inti. Berikut adalah contoh ekstensi rel:
class String
def starts_with?(other)
head = self[0, other.length]
head == other
end
end
Python (bayangkan tidak ada ''.startswith
metode):
def starts_with(s, prefix):
return s[:len(prefix)] == prefix
Anda bisa menggunakannya di urutan apa pun (bukan hanya string). Untuk menggunakannya, Anda harus mengimpornya secara eksplisit misalnya from some_module import starts_with
,.
Ruby memiliki fitur scripting seperti Perl
Ruby memiliki regexps kelas satu, $ -variables, awk / perl baris demi baris input loop dan fitur lain yang membuatnya lebih cocok untuk menulis skrip shell kecil yang munge file teks atau bertindak sebagai kode perekat untuk program lain.
Ruby memiliki kelanjutan kelas satu
Berkat pernyataan callcc. Di Python Anda dapat membuat kelanjutan dengan berbagai teknik, tetapi tidak ada dukungan bawaan untuk bahasa tersebut.
Ruby memiliki blok
Dengan pernyataan "do" Anda dapat membuat fungsi anonim multi-baris di Ruby, yang akan diteruskan sebagai argumen ke metode di depan do, dan dipanggil dari sana. Di Python, Anda akan melakukan ini baik dengan meneruskan metode atau dengan generator.
Rubi:
amethod { |here|
many=lines+of+code
goes(here)
}
Python (blok Ruby sesuai dengan konstruksi berbeda di Python):
with amethod() as here: # `amethod() is a context manager
many=lines+of+code
goes(here)
Atau
for here in amethod(): # `amethod()` is an iterable
many=lines+of+code
goes(here)
Atau
def function(here):
many=lines+of+code
goes(here)
amethod(function) # `function` is a callback
Menariknya, pernyataan kemudahan di Ruby untuk memanggil sebuah blok disebut "yield", yang dalam Python akan membuat generator.
Rubi:
def themethod
yield 5
end
themethod do |foo|
puts foo
end
Python:
def themethod():
yield 5
for foo in themethod():
print foo
Meskipun prinsipnya berbeda, hasilnya sangat mirip.
Ruby mendukung pemrograman gaya fungsional (seperti pipa) dengan lebih mudah
myList.map(&:description).reject(&:empty?).join("\n")
Python:
descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))
Python memiliki generator bawaan (yang digunakan seperti blok Ruby, seperti disebutkan di atas)
Python memiliki dukungan untuk generator dalam bahasa tersebut. Di Ruby 1.8 Anda dapat menggunakan modul generator yang menggunakan lanjutan untuk membuat generator dari sebuah blok. Atau, Anda bisa menggunakan blok / proc / lambda! Selain itu, di Ruby 1.9 Serat adalah, dan dapat digunakan sebagai, generator, dan kelas Enumerator adalah generator bawaan 4
docs.python.org memiliki contoh generator ini:
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
Bandingkan ini dengan contoh blok di atas.
Python memiliki penanganan ruang nama yang fleksibel
Di Ruby, saat Anda mengimpor file dengan require
, semua hal yang ditentukan dalam file itu akan berakhir di namespace global Anda. Ini menyebabkan polusi namespace. Solusi untuk itu adalah modul Ruby. Tetapi jika Anda membuat namespace dengan modul, maka Anda harus menggunakan namespace itu untuk mengakses kelas yang ada di dalamnya.
Dalam Python, file tersebut adalah modul, dan Anda dapat mengimpor nama yang ada di dalamnya from themodule import *
, sehingga mencemari namespace jika Anda mau. Tetapi Anda juga dapat mengimpor nama yang dipilih dengan from themodule import aname, another
atau Anda dapat dengan mudah import themodule
dan kemudian mengakses nama dengan themodule.aname
. Jika Anda ingin lebih banyak level di namespace Anda, Anda dapat memiliki paket, yang merupakan direktori dengan modul dan __init__.py
file.
Python memiliki docstrings
Docstring adalah string yang dilampirkan ke modul, fungsi, dan metode, serta dapat diintrospeksi saat runtime. Ini membantu untuk membuat hal-hal seperti perintah bantuan dan dokumentasi otomatis.
def frobnicate(bar):
"""frobnicate takes a bar and frobnicates it
>>> bar = Bar()
>>> bar.is_frobnicated()
False
>>> frobnicate(bar)
>>> bar.is_frobnicated()
True
"""
Yang setara dengan Ruby mirip dengan javadocs, dan terletak di atas metode, bukan di dalamnya. Mereka bisa diambil pada waktu proses dari file dengan menggunakan metode 1.9 Metode # source_location digunakan
Python memiliki banyak warisan
Ruby tidak ("sengaja" - lihat situs web Ruby, lihat di sini bagaimana hal itu dilakukan di Ruby ). Itu menggunakan kembali konsep modul sebagai jenis kelas abstrak.
Python memiliki pemahaman list / dict
Python:
res = [x*x for x in range(1, 10)]
Rubi:
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]
Rubi:
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'}
Rubi:
>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}
Python memiliki dekorator
Hal-hal yang mirip dengan dekorator juga dapat dibuat di Ruby, dan juga dapat dikatakan bahwa hal itu tidak sepenting di Python.
Perbedaan sintaks
Ruby membutuhkan "end" atau "}" untuk menutup semua cakupannya, sementara Python hanya menggunakan spasi. Baru-baru ini ada upaya di Ruby untuk mengizinkan indentasi hanya spasi putih http://github.com/michaeledgar/seamless