Es gibt viele Diskussionen über Python vs. Ruby, und ich finde sie alle völlig wenig hilfreich, weil sie sich alle umdrehen, warum Merkmal X in Sprache Y scheiße ist, oder dass behauptet wird, dass Sprache Y kein X hat, obwohl es tatsächlich so ist Ich weiß auch genau, warum ich Python bevorzuge, aber das ist auch subjektiv und würde niemandem bei der Auswahl helfen, da er vielleicht nicht den gleichen Geschmack in der Entwicklung hat wie ich.
Das würde es daher Es wäre interessant, die Unterschiede objektiv aufzulisten. Also keine Lambdas von "Python". Erklären Sie stattdessen, was Rubys Lambdas können, was Pythons nicht können. Keine Subjektivität. Beispielcode ist gut!
Bitte nicht mehrere Unterschiede in einer Antwort haben. Und stimmen Sie diejenigen ab, von denen Sie wissen, dass sie richtig sind, und abwärts diejenigen, von denen Sie wissen, dass sie falsch sind (oder subjektiv sind). Auch Unterschiede in der Syntax sind nicht interessant. Wir wissen, dass Python mit Einrückungen das macht, was Ruby mit Klammern und Enden macht, und dass @ in Python self heißt.
UPDATE: Dies ist jetzt ein Community-Wiki, also können wir hier die großen Unterschiede hinzufügen.
p>Ruby hat eine Klassenreferenz im Klassenkörper
In Ruby haben Sie bereits eine Referenz auf die Klasse (selbst) im Klassenkörper. In Python haben Sie keinen Verweis auf die Klasse, bis die Klassenkonstruktion abgeschlossen ist.
Ein Beispiel:
Klasse Kaka fügt sich selbst hinzu
self ist in diesem Fall die Klasse, und dieser Code würde "Kaka" ausgeben. Es gibt keine Möglichkeit, den Klassennamen auszudrucken oder auf andere Weise auf die Klasse vom Klassendefinitionskörper in Python (außerhalb Methodendefinitionen).
Alle Klassen sind in Ruby änderbar
Damit können Sie Erweiterungen für Kernklassen entwickeln. Hier ist ein Beispiel für eine Rails-Erweiterung:
class String def starts_with?(other) head = self[0, other.length] head == other end end
Python (stellen Sie sich vor, es gäbe kein "". startswith
method):
def starts_with(s, prefix): return s[:len(prefix)] == prefix
Du könnte es für jede Sequenz verwenden (nicht nur für Zeichenfolgen). Um es zu verwenden, sollten Sie es explizit importieren, zB from some_module import started_with
.
Ruby hat Perl-ähnliche Skriptfunktionen
Ruby hat erstklassige Regexps, $-Variablen, die awk/perl-Zeile-für-Zeile-Eingabeschleife und andere Features, die es besser geeignet machen, kleine Shell-Skripte zu schreiben, die Textdateien mungen oder als Glue-Code für andere Programme dienen.
Ruby hat erstklassige Fortsetzungen
Dank der callcc-Anweisung. In Python können Sie Fortsetzungen durch verschiedene Techniken erstellen, aber es gibt keine in die Sprache eingebaute Unterstützung.
Ruby hat Blöcke
Mit der "do"-Anweisung können Sie eine Multi- line anonyme Funktion in Ruby, die als Argument an die Methode vor do übergeben und von dort aufgerufen wird. In Python würden Sie dies stattdessen entweder durch Übergabe einer Methode oder mit Generatoren tun.
Ruby:
amethod { |here| viele=Zeilen+von+Code geht(hier) }
Python (Ruby-Blöcke entsprechen verschiedenen Konstrukten in Python):
mit amethod() als hier: # `amethod() ist ein Kontextmanager viele=Zeilen+von+Code geht(hier)
Oder
für hier in amethod() : # `amethod()` ist eine iterierbare viele=Zeilen+von+Code geht(hier)
Oder
def function(hier): many =lines+of+code goes(hier) amethod(function) # `function` ist ein Callback
Interessanterweise heißt die Convenience-Anweisung in Ruby zum Aufrufen eines Blocks "yield", was in Python erstellt einen Generator.
Ruby:
def themethod yield 5 end themethod do |foo| puts foo end
Python:
def themethod(): yield 5 for foo in themethod(): print foo
Obwohl die Prinzipien unterschiedlich sind, ist das Ergebnis auffallend ähnlich.
Ruby unterstützt die funktionale (pipe-ähnliche) Programmierung einfacher
myList.map(& :description).reject(&:empty?).join(" ")
Python:
descriptions = (f.description() for f in mylist) " ".join(filter(len, descriptions))
Python hat eingebaute Generatoren (die wie oben erwähnt wie Ruby-Blöcke verwendet werden)
Python unterstützt Generatoren in der Sprache. In Ruby 1.8 können Sie das Generatormodul verwenden, das Fortsetzungen verwendet, um einen Generator aus einem Block zu erstellen. Oder Sie könnten einfach einen Block/Proc/Lambda verwenden! Darüber hinaus sind Fibers in Ruby 1.9 Generatoren und können als solche verwendet werden, und die Enumerator-Klasse ist ein eingebauter Generator 4
docs.python. org hat dieses Generatorbeispiel:
def reverse(data): for index in range(len(data)-1, -1, -1): yield data[index]
Vergleichen Sie dies den obigen Blockbeispielen.
Python hat eine flexible Namensraumbehandlung
Wenn Sie in Ruby eine Datei mit require
, landen alle Dinge, die in dieser Datei definiert sind, in Ihrem globalen Namensraum. Dies verursacht Namespace-Verschmutzung. Die Lösung dafür sind Rubys-Module. Aber wenn Sie einen Namensraum mit einem Modul erstellen, dann müssen Sie diesen Namensraum verwenden, um auf die enthaltenen Klassen zuzugreifen.
In Python ist die Datei ein Modul, und Sie können die enthaltenen Namen mit importieren aus dem Modul import *
, wodurch der Namensraum verunreinigt wird, wenn Sie möchten. Sie können aber auch nur ausgewählte Namen mit from themodule import aname, another
importieren oder Sie können einfach dasModul importieren
und dann mit themodule.aname
auf die Namen zugreifen >. Wenn Sie mehr Ebenen in Ihrem Namensraum haben möchten, können Sie Pakete haben, die Verzeichnisse mit Modulen und einer __init__.py
-Datei sind.
Python hat Docstrings
Docstrings sind Zeichenfolgen, die an Module, Funktionen und Methoden angehängt sind und zur Laufzeit überprüft werden können. Dies hilft beim Erstellen von Dingen wie dem Hilfebefehl und automatischer Dokumentation.
def frobnicate(bar): """frobnicate nimmt einen Balken und frobnicate ihn >>> bar = Bar( ) >>> bar.is_frobnicated() Falsch >>> frobnicate(bar) >>> bar.is_frobnicated() Wahr """
Ruby "s-Äquivalente ähneln javadocs und befinden sich oberhalb der Methode statt innerhalb. Sie können zur Laufzeit aus den Dateien abgerufen werden, indem die Method#source_location von 1.9 verwendet wird Beispielverwendung
Python hat Mehrfachvererbung
Ruby nicht ("absichtlich" -- siehe Rubys Website, sehen Sie hier, wie es geht "ist in Ruby). Es verwendet das Modulkonzept als eine Art von abstrakten Klassen wieder.
Python hat List/Dict Comprehensions
Python:
res = [x* x für x im Bereich (1, 10)]
Ruby:
res = (0..9).map { |x| x * x }
Python:
>>> (x*x für x im Bereich (10)) <Generatorobjekt <genexpr> bei 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) für x,y in {1:2, 3:4}.items()} {1: "4", 3: "16"}
Rubin:
>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}] => {1=>"4", 3=>"16"}
Python hat Dekoratoren
Dinge, die Dekoratoren ähnlich sind, können auch in Ruby erstellt werden, und es kann auch argumentiert werden, dass sie nicht so notwendig sind wie in Python.
Syntaxunterschiede
Ruby benötigt "end" oder "}", um alle seine Gültigkeitsbereiche zu schließen, während Python verwendet nur Leerzeichen. Es gab kürzlich Versuche in Ruby, Einrückungen nur mit Leerzeichen zuzulassen http://github.com /michaeledgar/seamless