Python ve Ruby hakkında pek çok tartışma var ve ben hepsini tamamen yararsız buluyorum, çünkü hepsi X özelliğinin neden Y dilinde emdiğini ya da aslında bu Y dilinin X'e sahip olmadığını iddia ediyorlar. Ayrıca neden Python'u tercih ettiğimi de biliyorum, ama bu aynı zamanda özneldir ve gelişimde benim gibi aynı zevklere sahip olmayabilecekleri için kimseyi seçmesine yardımcı olmaz.
Bu nedenle, farklılıkları objektif olarak listelemek ilginç olacaktır. Yani "Python'un lambdasları berbat" değil. Bunun yerine Ruby'nin lambdaslarının Python'un yapamayacağını neler yapabileceğini açıklayın. Öznellik yok. Örnek kod iyi!
Bir cevapta birkaç farklılık yok, lütfen. Ve doğru olduğunu bildiklerinizi oylayın ve bildiklerinizi yanlış (veya öznel) yapın. Ayrıca, sözdizimindeki farklılıklar ilginç değildir. Python'un Ruby'nin parantez ve uçlarla ne yaptığını girintiyle yaptığını biliyoruz ve buna Python'da self denir.
GÜNCELLEME: Bu artık bir topluluk wiki'si, bu yüzden büyük farklılıkları buraya ekleyebiliriz.
Ruby sınıf gövdesinde bir sınıf referansı var
Ruby'de zaten sınıf gövdesindeki sınıf (benlik) için bir referansınız vardır. Python'da, sınıf inşaatı bitene kadar sınıfa referansınız yoktur.
Bir örnek:
class Kaka
puts self
end
bu durumda kendini sınıf, ve bu kod "Kaka" çıktı. Sınıf adını yazdırmanın veya başka yollarla Python'daki sınıf tanımı gövdesinden sınıfa erişmenin bir yolu yoktur (dış yöntem tanımları).
Tüm sınıflar Ruby'de değiştirilebilir
Bu, çekirdek sınıflara uzantılar geliştirmenizi sağlar. Bir ray uzantısına örnek:
class String
def starts_with?(other)
head = self[0, other.length]
head == other
end
end
Python (bir ''.startswithyöntem olmadığını hayal edin ):
def starts_with(s, prefix):
return s[:len(prefix)] == prefix
Herhangi bir dizide kullanabilirsiniz (sadece dizelerde değil). Kullanmak için açıkça almanız gerekir , örn from some_module import starts_with.
Ruby, Perl benzeri komut dosyası oluşturma özelliklerine sahiptir
Ruby, birinci sınıf normal ifadelere, $ değişkenli, satır satır giriş döngüsüne ve awk / perl satır giriş döngüsüne ve metin dosyalarını birleştiren veya diğer programlar için tutkal kodu görevi gören küçük kabuk komut dosyaları yazmaya daha uygun hale getiren diğer özelliklere sahiptir.
Ruby birinci sınıf devam ediyor
Callcc bildirimi sayesinde. Python'da çeşitli tekniklerle süreklilik oluşturabilirsiniz, ancak dilde yerleşik bir destek yoktur.
Ruby'nin blokları var
"Do" ifadesiyle Ruby'de do'nun önündeki yönteme argüman olarak iletilecek ve oradan çağrılacak çok satırlı anonim bir işlev oluşturabilirsiniz. Bunun yerine Python'da bunu bir yöntem geçirerek ya da jeneratörlerle yaparsınız.
Yakut:
amethod { |here|
many=lines+of+code
goes(here)
}
Python (Ruby blokları Python'daki farklı yapılara karşılık gelir):
with amethod() as here: # `amethod() is a context manager
many=lines+of+code
goes(here)
Veya
for here in amethod(): # `amethod()` is an iterable
many=lines+of+code
goes(here)
Veya
def function(here):
many=lines+of+code
goes(here)
amethod(function) # `function` is a callback
İlginç bir şekilde, Ruby'de bir blok çağırmak için uygunluk ifadesine Python'da bir jeneratör oluşturacak olan "verim" denir.
Yakut:
def themethod
yield 5
end
themethod do |foo|
puts foo
end
Python:
def themethod():
yield 5
for foo in themethod():
print foo
İlkeler farklı olmasına rağmen sonuç çarpıcı biçimde benzerdir.
Ruby, işlevsel stil (boru benzeri) programlamayı daha kolay destekler
myList.map(&:description).reject(&:empty?).join("\n")
Python:
descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))
Python'un yerleşik jeneratörleri vardır (bunlar yukarıda belirtildiği gibi Ruby blokları gibi kullanılır)
Python'un dilde jeneratörler için desteği var. Ruby 1.8'de bir bloktan jeneratör oluşturmak için süreklilikleri kullanan jeneratör modülünü kullanabilirsiniz. Veya sadece bir blok / proc / lambda kullanabilirsiniz! Dahası, Ruby 1.9'da Fiberler jeneratörlerdir ve kullanılabilirler ve Enumerator sınıfı yerleşik bir jeneratör 4'tür.
docs.python.org bu jeneratör örneğine sahiptir:
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
Bunu yukarıdaki blok örnekleriyle karşılaştırın.
Python'un esnek ad alanı kullanımı var
Ruby'de, bir dosyayı içe requireaktardığınızda, o dosyada tanımlanan her şey genel ad alanınızda sona erer. Bu, ad alanı kirliliğine neden olur. Bunun çözümü Rubys modülleridir. Ancak modülle bir ad alanı oluşturursanız, içerilen sınıflara erişmek için bu ad alanını kullanmanız gerekir.
Python'da dosya bir modüldür ve içerdiği adları ile içe aktarabilir from themodule import *, böylece isterseniz ad alanını kirletebilirsiniz. Ancak, yalnızca seçili adları ile içe aktarabilir from themodule import aname, anotherveya adlarına basitçe import themoduleve sonra erişebilirsiniz themodule.aname. Ad alanınızda daha fazla seviye istiyorsanız, modül ve __init__.pydosya içeren dizinler olabilir .
Python'un öğretileri var
Docstrings, modüllere, işlevlere ve yöntemlere bağlı olan ve çalışma zamanında içgözlenebilen dizelerdir. Bu, yardım komutu ve otomatik dokümantasyon gibi şeyler oluşturmanıza yardımcı olur.
def frobnicate(bar):
"""frobnicate takes a bar and frobnicates it
>>> bar = Bar()
>>> bar.is_frobnicated()
False
>>> frobnicate(bar)
>>> bar.is_frobnicated()
True
"""
Ruby'nin eşdeğeri javadoclara benzer ve içinde değil yöntemin üzerinde bulunur. 1.9'ın Yöntem # source_location örnek kullanımı kullanılarak çalışma zamanında dosyalardan alınabilirler
Python'un birden fazla mirası var
Ruby yapmaz ("bilerek" - Ruby'nin web sitesine bakın, Ruby'de nasıl yapıldığını buradan görebilirsiniz ). Modül kavramını bir tür soyut sınıf olarak yeniden kullanır.
Python'da liste / dikte anlama
Python:
res = [x*x for x in range(1, 10)]
Yakut:
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]
Yakut:
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'}
Yakut:
>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}
Python'un dekoratörleri var
Dekoratörlere benzer şeyler Ruby'de de oluşturulabilir ve Python'da olduğu kadar gerekli olmadıkları da iddia edilebilir.
Sözdizimi farklılıkları
Ruby, tüm kapsamlarını kapatmak için "son" veya "}" gerektirirken Python yalnızca beyaz boşluk kullanır. Ruby'de yalnızca boşluk girintisine izin verme girişimleri olmuştur http://github.com/michaeledgar/seamless