Was hat Ruby, was Python nicht hat und umgekehrt?

263

Es gibt viele Diskussionen zwischen Python und Ruby, und ich finde sie alle völlig wenig hilfreich, weil sie sich alle umdrehen, warum Feature X die Sprache Y nervt oder die Behauptung, dass die Sprache Y kein X hat, obwohl dies tatsächlich der Fall ist. Ich weiß auch genau, warum ich Python bevorzuge, aber das ist auch subjektiv und würde niemandem bei der Auswahl helfen, da sie möglicherweise nicht den gleichen Geschmack in der Entwicklung haben wie ich.

Es wäre daher interessant, die Unterschiede objektiv aufzulisten. Also kein "Pythons Lambdas saugt". Erklären Sie stattdessen, was Rubys Lambdas können, was Pythons nicht kann. Keine Subjektivität. Beispielcode ist gut!

Bitte haben Sie nicht mehrere Unterschiede in einer Antwort. Und stimmen Sie diejenigen ab, von denen Sie wissen, dass sie richtig sind, und diejenigen, von denen Sie wissen, dass sie falsch (oder subjektiv) sind. Auch Unterschiede in der Syntax sind nicht interessant. Wir wissen, dass Python mit Einrückungen macht, was Ruby mit Klammern und Enden macht, und dass @ in Python selbst heißt.

UPDATE: Dies ist jetzt ein Community-Wiki, daher können wir hier die großen Unterschiede hinzufügen.

Ruby hat eine Klassenreferenz im Klassenkörper

In Ruby haben Sie einen Verweis auf die Klasse (self), die sich bereits im Klassenkörper befindet. In Python haben Sie erst nach Abschluss der Klassenkonstruktion einen Verweis auf die Klasse.

Ein Beispiel:

class Kaka
  puts self
end

Selbst in diesem Fall ist die Klasse, und dieser Code würde "Kaka" ausdrucken. Es gibt keine Möglichkeit, den Klassennamen auszudrucken oder auf andere Weise über den Klassendefinitionskörper in Python (außerhalb von Methodendefinitionen) auf die Klasse zuzugreifen.

Alle Klassen sind in Ruby veränderbar

Auf diese Weise können Sie Erweiterungen für Kernklassen entwickeln. Hier ist ein Beispiel für eine Schienenverlängerung:

class String
  def starts_with?(other)
    head = self[0, other.length]
    head == other
  end
end

Python (stellen Sie sich vor, es gäbe keine ''.startswithMethode):

def starts_with(s, prefix):
    return s[:len(prefix)] == prefix

Sie können es für jede Sequenz verwenden (nicht nur für Zeichenfolgen). Um es zu verwenden, sollten Sie es explizit importieren, z from some_module import starts_with.

Ruby verfügt über Perl-ähnliche Skriptfunktionen

Ruby verfügt über erstklassige Regexps, $ -Variablen, die zeilenweise awk / perl-Eingabeschleife und andere Funktionen, die es besser geeignet machen, kleine Shell-Skripte zu schreiben, die Textdateien mischen oder als Klebercode für andere Programme dienen.

Ruby hat erstklassige Fortsetzungen

Dank der callcc-Anweisung. In Python können Sie Fortsetzungen mit verschiedenen Techniken erstellen, die Sprache ist jedoch nicht unterstützt.

Ruby hat Blöcke

Mit der Anweisung "do" können Sie in Ruby eine mehrzeilige anonyme Funktion erstellen, die als Argument an die Methode vor do übergeben und von dort aufgerufen wird. In Python würden Sie dies stattdessen entweder durch Übergeben einer Methode oder mit Generatoren tun.

Rubin:

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

Python (Ruby-Blöcke entsprechen verschiedenen Konstrukten in Python):

with amethod() as here: # `amethod() is a context manager
    many=lines+of+code
    goes(here)

Oder

for here in amethod(): # `amethod()` is an iterable
    many=lines+of+code
    goes(here)

Oder

def function(here):
    many=lines+of+code
    goes(here)

amethod(function)     # `function` is a callback

Interessanterweise heißt die Convenience-Anweisung in Ruby zum Aufrufen eines Blocks "Yield", wodurch in Python ein Generator erstellt wird.

Rubin:

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("\n")

Python:

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

Python verfügt über integrierte 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 und können in Ruby 1.9 Fasern als Generatoren verwendet werden, und die Enumerator-Klasse ist ein integrierter 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 mit den obigen Blockbeispielen.

Python verfügt über eine flexible Behandlung von Namensräumen

Wenn Sie in Ruby eine Datei mit importieren require, werden alle in dieser Datei definierten Elemente in Ihrem globalen Namespace gespeichert. Dies führt zu einer Verschmutzung des Namespace. Die Lösung dafür sind Rubys-Module. Wenn Sie jedoch einen Namespace mit einem Modul erstellen, müssen Sie diesen Namespace verwenden, um auf die enthaltenen Klassen zuzugreifen.

In Python ist die Datei ein Modul, und Sie können die darin enthaltenen Namen mit importieren from themodule import *, wodurch der Namespace verschmutzt wird, wenn Sie möchten. Sie können aber auch nur ausgewählte Namen mit importieren from themodule import aname, anotheroder einfach import themoduleund dann auf die Namen mit zugreifen themodule.aname. Wenn Sie mehr Ebenen in Ihrem Namespace wünschen, können Sie Pakete haben, die Verzeichnisse mit Modulen und einer __init__.pyDatei sind.

Python hat Docstrings

Docstrings sind Strings, 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 der automatischen Dokumentation.

def frobnicate(bar):
    """frobnicate takes a bar and frobnicates it

       >>> bar = Bar()
       >>> bar.is_frobnicated()
       False
       >>> frobnicate(bar)
       >>> bar.is_frobnicated()
       True
    """

Rubys Äquivalent ähnelt Javadocs und befindet sich über der Methode anstatt innerhalb dieser. Sie können zur Laufzeit aus den Dateien abgerufen werden, indem das Beispiel für die Methode # source_location von 1.9 verwendet wird

Python hat mehrere Vererbungen

Ruby nicht ("absichtlich" - siehe Rubys Website, hier erfahren Sie, wie es in Ruby gemacht wird ). Das Modulkonzept wird als eine Art abstrakter Klassen wiederverwendet.

Python hat Listen- / Dikt-Verständnis

Python:

res = [x*x for x in range(1, 10)]

Rubin:

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]

Rubin:

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'}

Rubin:

>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}

Python hat Dekorateure

Dinge, die Dekorateuren ä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 Bereiche zu schließen, während Python nur Leerzeichen verwendet. In Ruby wurden kürzlich Versuche unternommen, nur Leerzeichen einzurücken. Http://github.com/michaeledgar/seamless

Lennart Regebro
quelle
2
In Bezug auf Mehrfachvererbung ist es unaufrichtig, nur "Ruby nicht" zu sagen. Ich kann mir nichts vorstellen, was Sie in Python mit Mehrfachvererbung tun können, was Sie in Ruby mit Modulen / "Mixin-Vererbung" nicht tun können. (Es ist sogar fraglich, ob das Einschließen von Modulen einfach eine Mehrfachvererbung ist.)
Logan Capaldo
2
Dass Sie dasselbe auf andere Weise tun können, ist ein Argument, das nicht zutrifft. Sie können hier alles anders machen. Und da Module keine Klassen sind, handelt es sich nicht um Mehrfachvererbung. Sie können gerne Codebeispiele dazu beitragen, wie es in Pythons Mehrfachvererbung im Vergleich zu Rubys-Modulen funktioniert.
Lennart Regebro
3
Module sind keine Klassen, aber Klassen sind Module. % ruby ​​-e 'p Klasse <Modul' wahr
Logan Capaldo
8
-1 Leider verfehlt diese Frage ihr Ziel und die meisten angeblichen Unterschiede sind überhaupt keine Unterschiede, und es gibt viele Fehlinformationen!
Voreingenommenheit
2
Modul-Includes sind in der Tat Mehrfachvererbung, nicht nur im Konzept, sondern in der tatsächlichen Implementierung im Ruby-Interpreter. Wenn ein Ruby-Modul enthalten ist, wird es genauso in die Vererbungskette eingefügt wie Superklassen. Die Methodenauflösung ist dieselbe. In Ruby sind mehrere Modul-Includes Mehrfachvererbung. Wer dies als semantisch "nicht dasselbe" wie Mehrfachvererbung bestreiten will, ist nur pedantisch. Was bringt es, wenn etwas nicht dasselbe ist, wenn der Effekt identisch und genauso leicht zu erreichen ist? Eine Unterscheidung ohne Unterschied.
Dave Sims

Antworten:

34

Ruby hat die Konzepte von Blöcken , die im Wesentlichen syntaktischen Zucker um einen Codeabschnitt sind. Sie sind eine Möglichkeit, Abschlüsse zu erstellen und an eine andere Methode zu übergeben, die den Block verwenden kann oder nicht. Ein Block kann später über eine yieldAnweisung aufgerufen werden .

Eine einfache Definition einer eachMethode für Arraykönnte beispielsweise so aussehen:

class Array
  def each
    for i in self  
      yield(i)     # If a block has been passed, control will be passed here.
    end  
  end  
end  

Dann können Sie dies folgendermaßen aufrufen:

# Add five to each element.
[1, 2, 3, 4].each{ |e| puts e + 5 }
> [6, 7, 8, 9]

Python hat anonyme Funktionen / Verschlüsse / Lambdas, aber keine Blöcke, da ein Teil des nützlichen syntaktischen Zuckers fehlt. Es gibt jedoch mindestens einen Weg, um es ad-hoc zu bekommen. Siehe zum Beispiel hier .

John Feminella
quelle
6
@ Lennart: Abgesehen davon, dass dein Beispiel nur schrecklich ist, ist es auch syntaktisch falsch.
2
@unbeknow: A, richtig. Aber wenn das eine Funktion anstelle eines Drucks gewesen wäre, hätte es funktioniert. In Python 3 funktioniert dies: [print (e + 5) für e in [1,2,3,4]] Und wenn es um Schrecklichkeit geht, denke ich, dass der obige Ruby-Code schrecklich ist, also ist das eindeutig subjektiv und damit nicht a Teil dieser Frage. @ John Ich sage nicht, dass es gleichwertig ist, ich sage, es ist nicht offensichtlich, was der Unterschied zu Ihrem Beispiel ist. @ Bastien, nein, aber dass man ähnliche Dinge machen kann, heißt nicht, dass sie gleich sind. Unterschiede sollten hier aufgelistet werden, auch wenn es andere Möglichkeiten gibt, dies zu tun.
Lennart Regebro
22
Ich bin ein Python-Programmierer. Ich würde gerne ein Beispiel dafür sehen, wie Ruby-Blöcke Ihnen helfen, etwas prägnanter oder schöner zu schreiben als mit Python, weil es keine Blöcke enthält. Ihr Beispiel könnte geschrieben werden: für i in [1, 2, 3, 4]: print (i + 5). Es werden keine Blöcke verwendet, aber es ist prägnant und schön sowie der Rubin jedes Beispiels.
Manuel Ceron
10
@Manuel, procs sind nützlich, um Funktoren an nicht triviale Datenstrukturen (Bäume, Diagramme ...) anzuhängen, die nicht "for-looped" sein können und daher spezielle Iteratoren zum Überqueren erfordern. Mit Blöcken, bei denen es sich um anonyme Prozesse handelt, können Sie den Funktor in einem Ausdruck implementieren (vs. definieren, dann implementieren), was den Codierungsprozess erheblich beschleunigt und die Absicht verdeutlicht. Wenn Sie beispielsweise eine Diagrammdatenstruktur erstellen, können Sie einen 'jeden' Iterator definieren und dann Enumerable mischen, wodurch Sie sofort auf Dutzende von Iteratoren zugreifen können (sort, all?, Any?, Grep). Jetzt rufen Sie einen Block auf ...
Bias
4
@RommeDeSerieux, weil es einen Namen in der Sprache braucht! Außerdem ist es ein Funktionsobjekt, keine Funktion. Schauen wir uns die Ruby-Dokumente an: "Proc-Objekte sind Codeblöcke, die an eine Reihe lokaler Variablen gebunden wurden". Ein anonymer Proc ist also nur der Block und sicherlich nicht nur eine Funktion!
Voreingenommenheit
28

Python-Beispiel

Funktionen sind erstklassige Variablen in Python. Sie können eine Funktion deklarieren, als Objekt weitergeben und überschreiben:

def func(): print "hello"
def another_func(f): f()
another_func(func)

def func2(): print "goodbye"
func = func2

Dies ist ein grundlegendes Merkmal moderner Skriptsprachen. JavaScript und Lua machen das auch. Ruby behandelt Funktionen nicht so. Das Benennen einer Funktion ruft sie auf.

Natürlich gibt es in Ruby Möglichkeiten, diese Dinge zu tun, aber es handelt sich nicht um erstklassige Operationen. Sie können beispielsweise eine Funktion mit Proc.new umschließen, um sie als Variable zu behandeln. Dann ist sie jedoch keine Funktion mehr. Es ist ein Objekt mit einer "Aufruf" -Methode.

Rubys Funktionen sind keine erstklassigen Objekte

Ruby-Funktionen sind keine erstklassigen Objekte. Funktionen müssen in ein Objekt eingewickelt werden, um sie weiterzugeben. Das resultierende Objekt kann nicht wie eine Funktion behandelt werden. Funktionen können nicht erstklassig zugewiesen werden. Stattdessen muss eine Funktion in ihrem Containerobjekt aufgerufen werden, um sie zu ändern.

def func; p "Hello" end
def another_func(f); method(f)[] end
another_func(:func)      # => "Hello"

def func2; print "Goodbye!"
self.class.send(:define_method, :func, method(:func2))
func                     # => "Goodbye!"

method(:func).owner      # => Object
func                     # => "Goodbye!"
self.func                # => "Goodbye!"    
Voreingenommenheit
quelle
8
Du bist sehr verwirrt. Erstklassige Objekte werden durch Zuweisung zugewiesen: x = ynicht durch Aufruf self.class.send(:define_method, :func, method(:func2)). Ihr "Gegenbeispiel" zeigt, dass Rubys Funktionen nicht erstklassig sind. Wenn Sie nicht einverstanden sind, können Sie gerne Ihre eigene Antwort posten. Steck deine Verwirrung nicht in meine.
Glenn Maynard
7
Dinge, die def ... endin Ruby definiert sind, sind keine Funktionen. Es sind Methoden (wie Sie sie definiert haben Kernel). Methoden können ungebunden sein (unter Verwendung der #methodMethode), die dann Objekte sind. Das, was Ruby den Funktionen am nächsten kommt, sind ProcInstanzen, die auch Objekte sind und herumgereicht oder aufgerufen werden können. Es hat auch eine spezielle Syntax zum Übergeben eines einzelnen Rückrufs Procan eine Methode, wie John Feminella in seiner Antwort erläutert .
Rampion
4
@Glenn: Ich verstehe, was Sie sagen, aber ich würde mit der Behauptung streiten, dass Rubys Funktionen neu definiert werden - Methoden sind ein separates semantisches Konzept. Wenn Sie das Definitionsspiel spielen möchten, sind Prozeduren und keine Funktionen der wichtigste Code. Ich versuche nicht, schwierig zu sein, ich glaube nur, dass Definitionen und Genauigkeit wichtig sind. Ich bin damit einverstanden, dass das Manipulieren UnboundMethodeines PITA sein kann.
Rampion
5
@Glenn: Schönheit liegt im Auge des Betrachters. Trotzdem sind Methoden erstklassige Objekte, wenn sie die Definition erfüllen (in diesem Fall beziehe ich mich auf die Wikipedia-Definition). Vielleicht haben Sie eine andere Definition von erstklassig? Benötigen sie eine Platin-Vielfliegerkarte, um erstklassig zu werden?
Voreingenommenheit
4
@Glenn Schauen Sie sich den SO FAQ-Bereich an "Andere Leute können meine Sachen bearbeiten?!" - Dies ist ein Community-Wiki.
Voreingenommenheit
26

Letztendlich werden alle Antworten auf einer bestimmten Ebene subjektiv sein, und die bisher veröffentlichten Antworten beweisen ziemlich genau, dass Sie nicht auf eine Funktion verweisen können, die in der anderen Sprache nicht auf eine ebenso nette (wenn nicht ähnliche) Weise möglich ist , da beide Sprachen sehr prägnant und ausdrucksstark sind.

Ich mag Pythons Syntax. Sie müssen jedoch etwas tiefer als die Syntax graben, um die wahre Schönheit von Ruby zu finden. In Rubys Konsistenz liegt zenartige Schönheit. Obwohl kein triviales Beispiel dies vollständig erklären kann, werde ich versuchen, hier eines zu finden, um zu erklären, was ich meine.

Kehren Sie die Wörter in dieser Zeichenfolge um:

sentence = "backwards is sentence This"

Wenn Sie darüber nachdenken, wie Sie es tun würden, würden Sie Folgendes tun:

  1. Teilen Sie den Satz in Wörter auf
  2. Kehren Sie die Wörter um
  3. Verbinden Sie die Wörter wieder zu einer Zeichenfolge

In Ruby würden Sie Folgendes tun:

sentence.split.reverse.join ' '

Genau so, wie Sie darüber nachdenken, wird in derselben Reihenfolge eine Methode nach der anderen aufgerufen.

In Python würde es eher so aussehen:

" ".join(reversed(sentence.split()))

Es ist nicht schwer zu verstehen, aber es hat nicht ganz den gleichen Fluss. Das Thema (Satz) ist in der Mitte begraben. Die Operationen sind eine Mischung aus Funktionen und Objektmethoden. Dies ist ein triviales Beispiel, aber man entdeckt viele verschiedene Beispiele, wenn man wirklich mit Ruby arbeitet und es versteht, insbesondere bei nicht trivialen Aufgaben.

Mark Thomas
quelle
1
Genau. Ruby scheint natürlich zu fließen, wenn ich es schreibe, also ist "zenartig" ein guter Begriff.
der Blechmann
18

Python hat die Mentalität "Wir sind alle Erwachsene hier". Sie werden also feststellen, dass Ruby Dinge wie Konstanten hat, während Python dies nicht tut (obwohl Rubys Konstanten nur eine Warnung auslösen). Die Python-Denkweise ist, dass Sie, wenn Sie etwas konstant machen möchten, die Variablennamen in Großbuchstaben setzen und nicht ändern sollten.

Zum Beispiel Ruby:

>> PI = 3.14
=> 3.14
>> PI += 1
(irb):2: warning: already initialized constant PI
=> 4.14

Python:

>>> PI = 3.14
>>> PI += 1
>>> PI
4.1400000000000006
Jason Baker
quelle
19
Ha .. das erinnert mich nur daran, dass Sie zumindest in Python 2. * "True, False = False, True" ausführen konnten ... Ich glaube, sie haben das in Python 3.0 richtig behoben ... das sollten Sie tun daran gehindert werden.
Tom
11
Persönlich mag ich strenge Richtlinien, die von der Sprache durchgesetzt werden, weil dadurch der gesamte in dieser Sprache geschriebene Code konsistent wird. Es zwingt Sie, die Richtlinien zu befolgen, und Entwickler, die Ihren Code lesen, können auf einen Blick erkennen, was was ist. Während die meisten Python-Codierer denselben allgemeinen "Stil" verwenden, habe ich einige ziemlich große Inkonsistenzen gesehen, die in Ruby nicht möglich wären.
Sasha Chedygov
8
@bias - Ich bin mir nicht sicher, warum du mich abstimmst. Diese Antwort stimmt nicht mit der Python-Methode überein. Es ist nur eine Feststellung.
Jason Baker
13
@ Jason "Wir sind alle Erwachsene hier" ist eine Aussage über eine Tatsache? Ich möchte das eine Meinung nennen, die sich um ein Feature dreht, daher die Abwärtsabstimmung.
Bias
7
@bias - Zu sagen "wir sind alle Erwachsene hier" war nicht als geringfügig gemeint. Es ist ein inoffizielles Python-Motto, das meiner Meinung nach am besten hier erklärt wird: mail.python.org/pipermail/tutor/2003-October/025932.html
Evan Porter
18

Sie können in Python nur bestimmte Funktionen aus einem Modul importieren. In Ruby importieren Sie die gesamte Liste der Methoden. Sie könnten sie in Ruby "importieren", aber es geht nicht darum.

BEARBEITEN:

Nehmen wir dieses Ruby-Modul:


module Whatever
  def method1
  end

  def method2
  end
end

wenn Sie es in Ihren Code aufnehmen:


include Whatever

Sie werden sehen, dass sowohl Methode1 als auch Methode2 zu Ihrem Namespace hinzugefügt wurden. Sie können nicht nur method1 importieren . Sie importieren sie entweder beide oder Sie importieren sie überhaupt nicht. In Python können Sie nur die Methoden Ihrer Wahl importieren. Wenn dies einen Namen hätte, würde es vielleicht als selektiver Import bezeichnet werden?

Tempus
quelle
2
Oh, richtig! Python mag Namespaces. Ist das bei Ruby nicht der Fall? Du bist nicht import bla; bla.foo()in Ruby?
Lennart Regebro
2
Sie können nur die Funktion a importieren, nicht alle darin enthaltenen Funktionen. Wenn Sie beispielsweise ein Ruby-Modul einschließen, das drei nicht statische Funktionen deklariert, werden alle in Ihren Namespace aufgenommen. In Python müssten Sie vom Modulimport * schreiben.
Geo
6
Führt das nicht zu viel Unordnung im Namespace?
Lennart Regebro
1
Ich denke schon. Das hasse ich an Ruby-Modulen.
Geo
8
Ruby hat nicht wirklich ein Modulsystem im gleichen Sinne wie Python. erfordern Arbeiten im Grunde genommen als Textaufnahme mit einigen Überprüfungen für die Dupilikataufnahme. Sie können Module (ab) als Namespaces verwenden, sind aber moduleeigentlich eine Fehlbezeichnung. Die Module sind grundsätzlich Klassen sans die new, allocateMethoden. Sie eignen sich am besten als Methode zum Freigeben von Code pro Klasse / Objekt, nicht als Mechanismus zum Partitionieren von Bibliotheken oder zum Teilen von Code zwischen Programmen.
Logan Capaldo
16

Von Rubys Website :

Ähnlichkeiten Wie bei Python in Ruby, ...

  • Es gibt eine interaktive Eingabeaufforderung (irb genannt).
  • Sie können Dokumente in der Befehlszeile lesen (mit dem Befehl ri anstelle von pydoc).
  • Es gibt keine speziellen Leitungsterminatoren (außer der üblichen neuen Leitung).
  • String-Literale können mehrere Zeilen umfassen, wie Pythons dreifach zitierte Strings.
  • Klammern stehen für Listen und Klammern für Diktate (die in Ruby als "Hashes" bezeichnet werden).
  • Arrays funktionieren genauso (wenn Sie sie hinzufügen, entsteht ein langes Array, aber wenn Sie sie so zusammenstellen, erhalten a3 = [ a1, a2 ]Sie ein Array von Arrays).
  • Objekte werden stark und dynamisch typisiert.
  • Alles ist ein Objekt, und Variablen sind nur Verweise auf Objekte.
  • Obwohl die Schlüsselwörter etwas unterschiedlich sind, funktionieren Ausnahmen ungefähr gleich.
  • Sie haben eingebettete Dokumenttools (Ruby's heißt rdoc).

Unterschiede Im Gegensatz zu Python ...

  • Saiten sind veränderlich.
  • Sie können Konstanten erstellen (Variablen, deren Wert Sie nicht ändern möchten).
  • Es gibt einige erzwungene Groß- und Kleinschreibung (z. B. Klassennamen beginnen mit einem Großbuchstaben, Variablen beginnen mit einem Kleinbuchstaben).
  • Es gibt nur eine Art von Listencontainer (ein Array), der veränderbar ist.
  • Zeichenfolgen in doppelten Anführungszeichen ermöglichen Escape-Sequenzen (wie \ t) und eine spezielle Syntax für die "Substitution von Ausdrücken" (mit der Sie die Ergebnisse von Ruby-Ausdrücken direkt in andere Zeichenfolgen einfügen können, ohne "+" Zeichenfolgen "+" zusammen "hinzufügen zu müssen). . Zeichenfolgen in einfachen Anführungszeichen sind wie Pythons "rohe Zeichenfolgen".
  • Es gibt keine Klassen für "neuen Stil" und "alten Stil". Nur eine Art.
  • Sie greifen niemals direkt auf Attribute zu. Bei Ruby sind das alles Methodenaufrufe.
  • Klammern für Methodenaufrufe sind normalerweise optional.
  • Es gibt öffentliche, private und geschützte, um den Zugriff zu erzwingen, anstelle von Pythons _voluntary_ underscore __convention__.
  • "Mixins" werden anstelle der Mehrfachvererbung verwendet.
  • Sie können die Methoden der integrierten Klassen hinzufügen oder ändern. In beiden Sprachen können Sie Klassen jederzeit öffnen und ändern, Python verhindert jedoch das Ändern von integrierten Funktionen - Ruby nicht.
  • Sie haben wahr und falsch anstelle von wahr und falsch (und null anstelle von keiner).
  • Wenn auf Wahrheit geprüft, werden nur Falsch und Null zu einem falschen Wert bewertet. Alles andere ist wahr (einschließlich 0, 0.0, "" und []).
  • Es ist elsif statt elif.
  • Es ist erforderlich, anstatt zu importieren. Ansonsten ist die Verwendung jedoch dieselbe.
  • Die Kommentare im üblichen Stil in den Zeilen über den Dingen (anstelle der darunter liegenden Dokumentzeichenfolgen) werden zum Generieren von Dokumenten verwendet.
  • Es gibt eine Reihe von Verknüpfungen, die Sie schnell lernen, obwohl Sie mehr zu merken haben. Sie neigen dazu, Ruby lustig und sehr produktiv zu machen.
kruczkowski
quelle
2
"Es ist erforderlich, anstatt zu importieren. Ansonsten ist die Verwendung jedoch dieselbe." Scheint völlig ungenau zu sein.
Glenjamin
Es gibt auch Sets in Ruby, die nur selten verwendet werden, die jedoch integriert sind. Ich kann also sagen, stuff_in_backpack = Set.new; stuff_in_backpack << "Computer"; stuff_in_backpack << "Schuhe"; # und das Set enthält alle Werte, ohne die Reihenfolge zu garantieren.
Zachaysan
12

Was Ruby gegenüber Python hat, sind seine Skriptsprachenfunktionen. Skriptsprache in diesem Kontext, die für "Klebercode" in Shell-Skripten und allgemeine Textmanipulation verwendet werden soll.

Diese werden meistens mit Perl geteilt. Erstklassige integrierte reguläre Ausdrücke, $ -Variablen, nützliche Befehlszeilenoptionen wie Perl (-a, -e) usw.

Zusammen mit seiner knappen und dennoch ausdrucksstarken Syntax eignet es sich perfekt für diese Art von Aufgaben.

Python ist für mich eher eine dynamisch typisierte Geschäftssprache, die sehr einfach zu erlernen ist und eine ordentliche Syntax hat. Nicht so "cool" wie Ruby, aber ordentlich. Was Python für mich über Ruby hat, ist die große Anzahl von Bindungen für andere Bibliotheken. Bindungen an Qt und andere GUI-Bibliotheken, viele Spielunterstützungsbibliotheken und und und. Ruby hat viel weniger. Während häufig verwendete Bindungen, z. B. an Datenbanken, von guter Qualität sind, habe ich festgestellt, dass Nischenbibliotheken in Python besser unterstützt werden, selbst wenn für dieselbe Bibliothek auch eine Ruby-Bindung vorhanden ist.

Ich würde also sagen, dass beide Sprachen ihre Verwendung haben und es die Aufgabe ist, die definiert, welche verwendet werden soll. Beide sind leicht zu lernen. Ich benutze sie nebeneinander. Ruby für Skripte und Python für eigenständige Apps.

haffax
quelle
1
Frage von jemandem, der Ruby noch nicht kennt: Was meinst du mit "$ -Variablen"? Meinen Sie globale Variablen? In diesem Fall ist in Python eine in einem Modul außerhalb einer Klasse oder Funktion definierte Variable global. Wenn nicht - was ist der Unterschied?
Anon
1
Anon: Wenn Sie eine $ -Variable an einer beliebigen Stelle im Code deklarieren, ist sie aufgrund des Präfixes global. Es spielt also keine Rolle, wo es definiert ist, es ist immer global und immer als solches bekannt.
Robert K
8
Nicht genau, eigentlich meinte ich vordefinierte Variablen wie $ _, $ 1 usw. Diese werden von Ruby selbst automatisch mit Werten gefüllt. $ _ ist die letzte gelesene Zeile. $ 1, $ 2 usw. sind die Übereinstimmungen mit regulären Ausdrücken aus der letzten Übereinstimmung. Eine vollständige Liste finden Sie hier: zenspider.com/Languages/Ruby/QuickRef.html#17 Grundsätzlich handelt es sich um einen Hack für kompakte Skripte. Sie können alle Informationen auch über API-Aufrufe abrufen, aber mit $ Variablen ist es knapper. Solche Variablen passen einfach nicht zu Pythons Stil, sie haben sie absichtlich weggelassen.
Haffax
Vielen Dank für diesen Zenspider-Link - ich habe nach so etwas gesucht, um Ruby schnell (ohne Tutorial) kennenzulernen.
Anon
12

Ich denke nicht, dass "Ruby hat X und Python nicht, während Python Y hat und Ruby nicht" die nützlichste Art ist, es zu betrachten. Sie sind ziemlich ähnliche Sprachen mit vielen gemeinsamen Fähigkeiten.

Der Unterschied besteht zu einem großen Teil darin, was die Sprache elegant und lesbar macht. Um ein Beispiel zu verwenden, das Sie angesprochen haben, haben beide theoretisch Lambdas, aber Python-Programmierer neigen dazu, sie zu vermeiden, und Konstrukte, die mit ihnen erstellt wurden, sehen nicht annähernd so lesbar oder idiomatisch aus wie in Ruby. So in Python, wird ein guter Programmierer einen anderen Weg zur Lösung des Problems als würde er in Ruby nehmen will, nur weil es tatsächlich ist der bessere Weg , es zu tun.

Futter
quelle
5
Ich stimme zu, dass Lambdas nur einen begrenzten Umfang haben und in vielen Fällen nicht nützlich sind. Ich denke jedoch nicht, dass es fair ist zu sagen, dass Python-Programmierer sie wie die Pest meiden.
Jason Baker
1
Ich bin damit einverstanden, dass Lambdas häufig mit Python verwendet werden - wie mit Map, Filter, Reduce. Der große Unterschied scheint zu sein, dass Python-Lambdas auf Ausdrücke beschränkt sind, während Ruby-Blöcke mehrzeilig sein und Anweisungen enthalten können. Mein allgemeiner Eindruck von dem, was ich über Ruby gelesen habe, ist, dass diese Funktion insbesondere Rubyisten dazu bringt, sich für den DSL-Ansatz zu entscheiden, während Pythonisten eher APIs erstellen. Meine Informationen zu Ruby sind jedoch immer noch sehr oberflächlich.
Anon
2
@Lennart: Mehrzeilige Blöcke werden in Ruby ständig verwendet - häufiger als Lambdas, die im idiomatischen Python-Code verwendet werden. Ein allgemeines Beispiel finden Sie unter info.michael-simons.eu/2007/08/06/rails-respond_to-method .
Chuck
1
@ Lennart: Nein, es wird kein Ertrag verwendet. (Rubys Ausbeute unterscheidet sich sowieso völlig von der von Python - es gibt keinen Generator zurück.) Es wäre nicht sinnvoll zu schreiben for format in respond_to(). Die respond_toMethode gibt nichts Sinnvolles zurück - sie antwortet einfach auf die aktuelle HTTP-Anfrage. Das doIn respond_to doist der Anfang eines Blocks. In diesem Block sprechen wir mit einem temporären Objekt ( formatin diesem Beispiel gekennzeichnet), das ein sehr einfaches DSL implementiert, um auf eine HTTP-Anfrage zu antworten.
Chuck
3
Können Sie Enumerable gegen einen Generator mischen und sofort 30 neue und wundervolle Iteratoren erhalten? Sie müssen sich die Sprache im Ganzen ansehen, bevor Sie verstehen, warum Blöcke / Prozesse großartig sind.
Voreingenommenheit
12

Ich möchte eine Variante der ursprünglichen Frage vorschlagen: "Was hat Ruby, was Python nicht hat, und umgekehrt?" was die enttäuschende Antwort zulässt: "Nun, was können Sie mit Ruby oder Python tun, was in Intercal nicht möglich ist?" Nichts auf dieser Ebene, denn Python und Ruby sind beide Teil der riesigen königlichen Familie, die auf dem Thron der Turing-Annäherung sitzt.

Aber was ist damit:

Was kann in Python anmutig und gut gemacht werden, was in Ruby nicht mit so viel Schönheit und guter Technik gemacht werden kann, oder umgekehrt?

Das ist vielleicht viel interessanter als nur ein Funktionsvergleich.

Christos Hayward
quelle
bestenfalls ein Kommentar. immer noch mein +1
nawfal
11

Python verfügt über eine explizite, integrierte Syntax für Listenerfassungen und Generatoren, während Sie in Ruby Map- und Codeblöcke verwenden würden.

Vergleichen Sie

list = [ x*x for x in range(1, 10) ]

zu

res = (1..10).map{ |x| x*x }
Dario
quelle
Wie ist Listenverständnis kein einfaches Python ? und es gibt auch eine Kartenfunktion in Python.
SilentGhost
Aber es gibt keine Listenverständnis-Syntax in Ruby
Dario
Python: res = map (Lambda x: x * x, Bereich (1,10))
GogaRieger
Python:res=map(2 .__rpow__, range(1,10))
John La Rooy
11

"Variablen, die mit einem Großbuchstaben beginnen, werden zu Konstanten und können nicht geändert werden."

Falsch. Sie können.

Sie erhalten nur dann eine Warnung, wenn Sie dies tun.

Kennzeichen
quelle
2
Wenn eine Sprache Sie vor einer Operation warnt, können Sie die Operation meiner Meinung nach sehr gut als "nicht möglich" betrachten. Alles andere ist Wahnsinn.
Porgarmingduod
11

Etwas mehr auf der Infrastrukturseite:

  • Python lässt sich viel besser in C ++ integrieren (über Boost.Python , SIP und Py ++ ) als Ruby, wobei die Optionen entweder direkt in die Ruby-Interpreter-API geschrieben werden (was Sie natürlich auch mit Python tun können). In beiden Fällen ist dies jedoch auf niedrigem Niveau, langwierig und fehleranfällig) oder Sie verwenden SWIG (was zwar funktioniert und auf jeden Fall großartig ist, wenn Sie viele Sprachen unterstützen möchten, aber bei weitem nicht so gut ist wie Boost.Python oder SIP, wenn Sie möchten speziell C ++ binden).

  • Python hat eine Reihe von Webanwendungsumgebungen (Django, Pylons / Turbogears, web.py, wahrscheinlich mindestens ein halbes Dutzend andere), während Ruby (effektiv) eine hat: Rails. (Andere Ruby-Webframeworks existieren zwar, haben aber anscheinend Schwierigkeiten, sich gegen Rails durchzusetzen). Ist dieser Aspekt gut oder schlecht? Schwer zu sagen und wahrscheinlich ziemlich subjektiv; Ich kann mir leicht Argumente vorstellen, dass die Python-Situation besser und die Ruby-Situation besser ist.

  • Kulturell gesehen scheinen die Python- und Ruby-Communitys etwas anders zu sein, aber ich kann nur darauf hinweisen, da ich nicht so viel Erfahrung mit der Ruby-Community habe. Ich füge dies hauptsächlich in der Hoffnung hinzu, dass jemand, der viel Erfahrung mit beiden hat, diese Aussage verstärken (oder ablehnen) kann.

Jack Lloyd
quelle
7
Ihr zweiter Punkt ist bestenfalls falsch informiert. Sie sollten beginnen, indem Sie Rack und Sinatra
Max Ogden
6
Ich stelle ausdrücklich fest, dass andere Rails-Stapel vorhanden sind. Ich glaube einfach nicht, dass jemand sie tatsächlich benutzt. Das Überprüfen von Sinatra und Rack änderte diesen Eindruck nicht genau. Denken Sie wirklich, dass beispielsweise Sinatra (insgesamt 94 SO-Fragen) oder Camping (insgesamt 2 SO-Fragen) oder eine der anderen tatsächlich eine echte Nutzerbasis / Community hat? Die meisten von ihnen haben nicht einmal echte Benutzer, soweit ich das beurteilen kann. Vergleichen Sie mit Django (4K +) oder Rails (7K +) oder sogar web.py.
Jack Lloyd
1
Sinatra ist aufgrund seines DSL für verschiedene, leichte Aufgaben sehr beliebt. Es wird nur weniger verwendet, weil die MVC von Rail mehr bietet. Rails ist eigentlich auf Rack aufgebaut - das macht Phusion Passenger möglich.
Alternative
11

Schamlos kopieren / einfügen von: Alex Martelli antwortet auf den Thread " Was ist besser an Ruby als Python ? " Aus der Mailingliste comp.lang.python .

18. August 2003, 10:50 Uhr Erik Max Francis schrieb:

"Brandon J. Van Every" schrieb:

Was ist besser an Ruby als an Python? Ich bin sicher, dass es etwas gibt. Was ist es?

Wäre es nicht viel sinnvoller, Ruby-Leute danach zu fragen, als Python-Leute?

Könnte oder könnte nicht, abhängig von den eigenen Zwecken - zum Beispiel, wenn die eigenen Zwecke eine "soziologische Studie" der Python-Community beinhalten, ist es wahrscheinlich, dass das Stellen von Fragen an diese Community aufschlussreichere Informationen darüber liefert, als sie an anderer Stelle zu platzieren :-).

Persönlich nutzte ich gerne die Gelegenheit, um das eintägige Ruby-Tutorial von Dave Thomas bei OSCON zu verfolgen. Unter einem dünnen Furnier von Syntaxunterschieden finde ich Ruby und Python erstaunlich ähnlich - wenn ich den minimalen Spannbaum unter nahezu allen Sprachen berechnen würde, wären Python und Ruby die ersten beiden Blätter, in denen sie zusammenwachsen würden ein Zwischenknoten :-).

Sicher, ich werde es müde, in Ruby das alberne "Ende" am Ende jedes Blocks einzugeben (anstatt nur einzurücken) - aber dann vermeide ich es, das ebenso alberne ":" einzugeben, das Python bei benötigt der Anfang jedes Blocks, das ist also fast eine Wäsche :-). Andere Syntaxunterschiede wie '@foo' gegenüber 'self.foo' oder die höhere Bedeutung von case in Ruby vs Python sind für mich genauso irrelevant.

Andere stützen ihre Wahl der Programmiersprachen zweifellos auf solche Themen und generieren die heißesten Debatten - aber für mich ist dies nur ein Beispiel für eines der geltenden Parkinson-Gesetze (der Umfang der Debatten zu einem Thema ist umgekehrt proportional zum Thema tatsächliche Bedeutung).

Bearbeiten (bis zum 19.06.2010, 11:45 Uhr): Dies wird auch als "Bikesheding malen" (oder kurz "Bikeshedding") bezeichnet - der Verweis bezieht sich wiederum auf Northcote Parkinson, der "Debatten" geführt hat auf welche Farbe das Bikeshed zu malen ist "als typisches Beispiel für" heiße Debatten über triviale Themen ". (Ende der Bearbeitung).

Ein Syntaxunterschied, den ich für wichtig halte und der Python zugute kommt - aber andere Leute werden zweifellos genau das Gegenteil denken - ist "wie ruft man eine Funktion auf, die keine Parameter akzeptiert". In Python (wie in C) wenden Sie zum Aufrufen einer Funktion immer den "Aufrufoperator" an - nachgestellte Klammern direkt nach dem Objekt, das Sie aufrufen (in diesen nachfolgenden Klammern stehen die Argumente, die Sie im Aufruf übergeben - wenn Wenn Sie keine Argumente übergeben, sind die Klammern leer. Dies lässt die bloße Erwähnung von irgendwelchenObjekt ohne beteiligten Operator, dh nur als Verweis auf das Objekt - in jedem Kontext ohne Sonderfälle, Ausnahmen, Ad-hoc-Regeln und dergleichen. In Ruby (wie in Pascal) übergeben Sie zum Aufrufen einer Funktion MIT Argumenten die Argumente (normalerweise in Klammern, obwohl dies nicht immer der Fall ist) - ABER wenn die Funktion keine Argumente akzeptiert, wird sie durch einfaches Erwähnen der Funktion implizit aufgerufen. Dies mag die Erwartungen vieler Menschen erfüllen (zumindest zweifellos derer, deren einzige Programmiererfahrung zuvor mit Pascal oder anderen Sprachen mit ähnlichen "impliziten Aufrufen" wie Visual Basic gemacht wurde) - aber für mich bedeutet es das Die bloße Erwähnung eines Objekts kann entweder einen Verweis auf das Objekt oder einen Aufruf des Objekts bedeuten, je nach Objekttyp - und in den Fällen, in denen ich kann. Um einen Verweis auf das Objekt zu erhalten, indem ich es nur erwähne, muss ich explizit "Gib mir einen Verweis darauf, nenne es NICHT!" verwenden. Operatoren, die sonst nicht benötigt werden. Ich bin der Meinung, dass dies die "Erstklassigkeit" von Funktionen (oder Methoden oder anderen aufrufbaren Objekten) und die Möglichkeit des reibungslosen Austauschs von Objekten beeinflusst. Daher ist dieser spezifische Syntaxunterschied für mich ein schwerwiegender schwarzer Fleck gegen Ruby - aber ich verstehe, warum andere etwas anderes tun würden, obwohl ich ihnen kaum vehementer widersprechen könnte :-). von Funktionen (oder Methoden oder anderen aufrufbaren Objekten) und die Möglichkeit, Objekte reibungslos auszutauschen. Daher ist dieser spezifische Syntaxunterschied für mich ein schwerwiegender schwarzer Fleck gegen Ruby - aber ich verstehe, warum andere etwas anderes tun würden, obwohl ich ihnen kaum vehementer widersprechen könnte :-). von Funktionen (oder Methoden oder anderen aufrufbaren Objekten) und die Möglichkeit, Objekte reibungslos auszutauschen. Daher ist dieser spezifische Syntaxunterschied für mich ein schwerwiegender schwarzer Fleck gegen Ruby - aber ich verstehe, warum andere etwas anderes tun würden, obwohl ich ihnen kaum vehementer widersprechen könnte :-).

Unterhalb der Syntax stoßen wir auf einige wichtige Unterschiede in der elementaren Semantik - zum Beispiel sind Strings in Ruby veränderbare Objekte (wie in C ++), während sie in Python nicht veränderbar sind (wie in Java oder ich glaube C #). Wiederum denken Leute, die in erster Linie nach dem urteilen, was sie bereits kennen, vielleicht, dass dies ein Plus für Ruby ist (es sei denn, sie kennen Java oder C # natürlich :-). Ich denke, unveränderliche Zeichenfolgen sind eine hervorragende Idee (und ich bin nicht überrascht, dass Java diese Idee, die bereits in Python enthalten war, unabhängig neu erfunden hat), obwohl es mir auch nichts ausmachen würde, einen "veränderlichen Zeichenfolgenpuffer" zu haben (und idealerweise eine mit einer besseren Benutzerfreundlichkeit als Javas eigene "String-Puffer"); und ich gebe dieses Urteil wegen Vertrautheit nicht ab - bevor ich Java studiere, Alle Daten sind unveränderlich, alle Sprachen, die ich kannte, hatten veränderbare Zeichenfolgen - doch als ich die Idee der unveränderlichen Zeichenfolgen in Java zum ersten Mal sah (die ich gut gelernt hatte, bevor ich Python lernte), kam sie mir sofort als ausgezeichnet vor, eine sehr gute Passform für Die Referenzsemantik einer höheren Programmiersprache (im Gegensatz zur Wertesemantik, die am besten zu Sprachen passt, die näher an der Maschine und weiter von Anwendungen wie C entfernt sind) mit Zeichenfolgen als erstklassige, integrierte (und hübsche) Sprache entscheidend) Datentyp.

Ruby hat einige Vorteile in der elementaren Semantik - zum Beispiel das Entfernen von Pythons "Listen gegen Tupel", die eine äußerst subtile Unterscheidung treffen. Aber meistens ist die Partitur (wie ich es halte, mit Einfachheit ein großes Plus und subtile, kluge Unterscheidungen ein bemerkenswertes Minus) gegen Ruby (z. B. mit geschlossenen und halboffenen Intervallen, mit den Notationen a..b und a .. .b [jemand möchte behaupten, dass es offensichtlich ist ist, welches welches ist? -)], ist albern - IMHO natürlich!). Wiederum werden Leute, die viele ähnliche, aber subtil unterschiedliche Dinge im Kern einer Sprache als PLUS und nicht als MINUS betrachten, diese natürlich "umgekehrt" zählen, wie ich sie zähle :-).

Lassen Sie sich durch diese Vergleiche nicht irreführen, zu denken, dass die beiden Sprachen es sind sehr sindanders, wohlgemerkt. Sie sind nicht. Aber wenn ich gebeten werde, "capelli d'angelo" mit "spaghettini" zu vergleichen, nachdem ich darauf hingewiesen habe, dass diese beiden Arten von Nudeln für niemanden zu unterscheiden sind und in jedem Gericht, das Sie zubereiten möchten, austauschbar sind, hätte ich dies unweigerlich getan um mikroskopisch zu untersuchen, wie sich die Längen und Durchmesser unmerklich unterscheiden, wie sich die Enden der Stränge in einem Fall verjüngen und nicht in dem anderen, und so weiter - um zu erklären, warum ich persönlich lieber capelli d hätte 'angelo wie die Nudeln in jeder Art von Brühe, aber ich würde Spaghettini als die Pastasciutta bevorzugen, um zu geeigneten Saucen für solch lange, dünne Nudelformen (Olivenöl, gehackter Knoblauch, gehackte rote Paprika und fein gemahlene Sardellen) zu passen. Zum Beispiel: Wenn Sie jedoch Knoblauch und Paprika in Scheiben schneiden, anstatt sie zu zerkleinern, sollten Sie den solideren Körper der Spaghetti anstelle der dünneren Vergänglichkeit der Spaghettini wählen. Es wäre ratsam, auf die Sardellen zu verzichten und stattdessen frisches Frühlingsbasilikum hinzuzufügen [ oder sogar - ich bin ein Ketzer ...! - leichte Minze ...] Blätter - im allerletzten Moment vor dem Servieren des Gerichts). Ups, sorry, es zeigt, dass ich ins Ausland reise und seit einer Weile keine Pasta mehr hatte, denke ich. Aber die Analogie ist immer noch ziemlich gut! -) - leichte Minze ...] Blätter - im allerletzten Moment vor dem Servieren des Gerichts). Ups, sorry, es zeigt, dass ich ins Ausland reise und seit einer Weile keine Pasta mehr hatte, denke ich. Aber die Analogie ist immer noch ziemlich gut! -) - leichte Minze ...] Blätter - im allerletzten Moment vor dem Servieren des Gerichts). Ups, sorry, es zeigt, dass ich ins Ausland reise und seit einer Weile keine Pasta mehr hatte, denke ich. Aber die Analogie ist immer noch ziemlich gut! -)

Zurück zu Python und Ruby kommen wir also zu den beiden Biggies (in Bezug auf die eigentliche Sprache - Verlassen der Bibliotheken und anderer wichtiger Hilfsmittel wie Tools und Umgebungen, Einbetten / Erweitern jeder Sprache usw. usw.) es für den Moment - sie würden sowieso nicht für alle UMSETZUNGEN jeder Sprache gelten, z. B. Jython vs Classic Python sind zwei Implementierungen der Python-Sprache!):

  1. Rubys Iteratoren und Codeblöcke gegen Pythons Iteratoren und Generatoren;

  2. Rubys GESAMTE, ungezügelte "Dynamik", einschließlich der Fähigkeit
    , jede vorhandene Klasse, einschließlich aller integrierten, "wieder zu öffnen" und ihr Verhalten zur Laufzeit zu ändern - im Vergleich zu Pythons enormer, aber begrenzter Dynamik, die das Verhalten der vorhandenen niemals ändert eingebaute Klassen und ihre Instanzen.

Persönlich halte ich 1 für eine Wäsche (die Unterschiede sind so tief, dass ich leicht Leute sehen konnte, die beide Ansätze hassen und die anderen verehren, aber auf MEINER persönlichen Skala sind die Vor- und Nachteile fast ausgeglichen); und 2 ein entscheidendes Problem - eines, das Ruby viel besser zum "Basteln" geeignet macht, ABER Python eignet sich gleichermaßen für den Einsatz in großen Produktionsanwendungen. In gewisser Weise ist es lustig, weil beide Sprachen so VIEL dynamischer sind als die meisten anderen, dass der entscheidende Unterschied zwischen ihnen und meinem POV letztendlich davon abhängen sollte - dass Ruby in dieser Hinsicht "auf elf geht" (die Referenz) hier ist natürlich "Spinal Tap"). In Ruby,Ich kann das tun ! Dh ich kann die eingebaute String-Klasse dynamisch so ändern, dass a = "Hallo Welt" b = "Hallo Welt", wenn a == b "gleich! \ N" druckt, sonst "anders drucken! \ N" Ende wird gedruckt " gleich". In Python gibt es keine Möglichkeit, das zu tun. Für die Zwecke der Metaprogrammierung, der Implementierung experimenteller Frameworks und dergleichen ist diese erstaunliche dynamische Fähigkeit von Ruby äußerst reizvoll. ABER - wenn es sich um große Anwendungen handelt, die von vielen Menschen entwickelt und von noch mehr verwaltet werden, einschließlich aller Arten von Bibliotheken aus verschiedenen Quellen, und die an Kundenstandorten in Produktion gehen müssen ... nun, ich will nicht Eine Sprache, die so dynamisch ist, vielen Dank. Ich verabscheue die Idee, dass eine Bibliothek unabsichtlich andere nicht verwandte unterbricht, die darauf beruhen, dass diese Zeichenfolgen unterschiedlich sind - das ist die Art von tief und tief verborgenem "Kanal" zwischen Codeteilen, die getrennt aussehen und getrennt sein sollten, der den Tod bedeutet groß angelegte Programmierung. Indem jedes Modul das Verhalten eines anderen "verdeckt" beeinflusst, ist die Fähigkeit, die Semantik integrierter Typen zu mutieren, nur eine schlechte Idee für die Programmierung von Produktionsanwendungen.

Wenn ich Ruby für eine so große Anwendung verwenden müsste, würde ich versuchen, mich auf Einschränkungen im Codierungsstil, viele Tests (die wiederholt werden müssen, wenn sich etwas ändert - auch was völlig unabhängig sein sollte ...) und dergleichen zu verlassen. die Verwendung dieser Sprachfunktion zu verbieten. Aber die Funktion NICHT überhaupt zu haben, ist meiner Meinung nach sogar noch besser - genau wie Python selbst eine noch bessere Sprache für die Anwendungsprogrammierung wäre, wenn eine bestimmte Anzahl von integrierten Funktionen "festgenagelt" werden könnte, also WUSSTE ich das zB ist len ​​("ciao") 4 (anstatt sich unterschwellig darum kümmern zu müssen, ob jemand die Bindung des Namens 'len' im eingebauten Modul geändert hat ...). Ich hoffe, dass Python irgendwann seine eingebauten "festnagelt".

Das Problem ist jedoch geringfügig, da das erneute Binden von integrierten Funktionen in Python sowohl eine veraltete als auch eine seltene Praxis ist. In Ruby scheint es mir wichtig zu sein - genau wie die zu leistungsfähigen Makrofunktionen anderer Sprachen (wie zum Beispiel Dylan) meiner Meinung nach ähnliche Risiken bergen (ich hoffe, dass Python niemals ein so leistungsfähiges Makrosystem bekommt, nein Der Reiz, "die Leute ihre eigenen domänenspezifischen kleinen Sprachen definieren zu lassen, die in die Sprache selbst eingebettet sind", würde meiner Meinung nach Pythons wunderbare Nützlichkeit für die Anwendungsprogrammierung beeinträchtigen, indem sie dem angehenden Bastler ein "attraktives Ärgernis" darstellen lauert im Herzen eines jeden Programmierers ...).

Alex

OscarRyz
quelle
9

Einige andere aus:

http://www.ruby-lang.org/de/documentation/ruby-from-other-languages/to-ruby-from-python/

(Wenn ich etwas falsch interpretiert habe oder sich eines dieser Elemente auf der Ruby-Seite geändert hat, seit diese Seite aktualisiert wurde, kann jemand es bearbeiten ...)

Zeichenfolgen können in Ruby geändert werden, nicht in Python (wo neue Zeichenfolgen durch "Änderungen" erstellt werden).

Ruby hat einige erzwungene Fallkonventionen, Python nicht.

Python hat sowohl Listen als auch Tupel (unveränderliche Listen). Ruby hat Arrays, die Python-Listen entsprechen, aber keine unveränderliche Variante davon.

In Python können Sie direkt auf Objektattribute zugreifen. In Ruby erfolgt dies immer über Methoden.

In Ruby sind Klammern für Methodenaufrufe normalerweise optional, in Python jedoch nicht.

Ruby ist öffentlich, privat und geschützt, um den Zugriff zu erzwingen, anstatt Pythons Konvention, Unterstriche und Namensverknüpfungen zu verwenden.

Python hat mehrere Vererbungen. Ruby hat "Mixins".

Und noch ein sehr relevanter Link:

http://c2.com/cgi/wiki?PythonVsRuby

Was insbesondere auf einen anderen guten von Alex Martelli verweist , der auch hier auf SO eine Menge großartiger Sachen gepostet hat:

http://groups.google.com/group/comp.lang.python/msg/028422d707512283

Anon
quelle
1
In Ruby können Sie Ihr Array einfach einfrieren, um es in etwas Unveränderliches zu ändern
user163365
Ausgezeichneter Beitrag von Alex Martelli :)
Skilldrick
8

Ich bin mir nicht sicher, also füge ich es zuerst als Antwort hinzu.

Python behandelt ungebundene Methoden als Funktionen

Das heißt, Sie können eine Methode entweder wie theobject.themethod()oder von aufrufen TheClass.themethod(anobject).

Bearbeiten: Obwohl der Unterschied zwischen Methoden und Funktionen in Python gering und in Python 3 nicht vorhanden ist, ist er auch in Ruby nicht vorhanden, einfach weil Ruby keine Funktionen hat. Wenn Sie Funktionen definieren, definieren Sie tatsächlich Methoden für Object.

Sie können die Methode einer Klasse jedoch immer noch nicht als Funktion aufrufen. Sie müssten sie erneut an das Objekt binden, das Sie aufrufen möchten, was viel schwieriger ist.

Lennart Regebro
quelle
Ruby hat überhaupt keine Funktionen. Das heißt, TheClass.instance_method(:themethod).bind(anobject).callwäre der entsprechende Rubin.
Logan Capaldo
Oh. Es gibt also eine Art magische Hauptklasse, wenn Sie eine Funktion definieren, die nicht zu einer expliziten Klasse gehört?
Lennart Regebro
Ja, auf der obersten Ebene definierte Methoden sind private Methoden von Object.
Logan Capaldo
1
FWIW, es scheint, dass in Python Funktionen und Methoden tatsächlich vom gleichen Typ sind und ihr unterschiedliches Verhalten von Deskriptoren herrührt : users.rcn.com/python/download/… .
Bastien Léonard
1
Wenn Sie es jedoch an ein Objekt binden, ist es nicht ungebunden. Duh. :-) Und sie sind auch in Python dasselbe. Es ist nur so, dass Ruby eigentlich keine Funktionen hat. Und das bedeutet, dass meine Aussage richtig ist. Sie können eine ungebundene Methode aufrufen, als wäre sie eine Funktion in Python. Und das ist tatsächlich nützlich, das heißt zum Beispiel, dass Sie eine für eine Klasse definierte Methode für ein Objekt aufrufen können, das diese Klasse nicht hat, was manchmal nützlich ist.
Lennart Regebro
7

Ich möchte die Python-Deskriptor-API erwähnen, mit der man die "Kommunikation" zwischen Objekt und Attribut anpassen kann. Es ist auch bemerkenswert, dass es in Python frei ist, ein alternatives Protokoll zu implementieren, indem der durch die Standardimplementierung der __getattribute__Methode vorgegebene Standard überschrieben wird. Lassen Sie mich näher auf die oben genannten Punkte eingehen. Deskriptoren sind regelmäßige Klassen mit __get__, __set__und / oder __delete__Methoden. Wenn der Dolmetscher auf so etwas stößt anObj.anAttr, wird Folgendes ausgeführt:

  • __getattribute__Methode von anObjwird aufgerufen
  • __getattribute__ Ruft ein Attr-Objekt aus dem Klassendikt ab
  • er prüft , ob abAttr Objekt hat __get__, __set__oder __delete__aufrufbare Objekte
  • Der Kontext (dh das Aufruferobjekt oder die Klasse und der Wert anstelle des letzteren, wenn wir einen Setter haben) wird an das aufrufbare Objekt übergeben
  • Das Ergebnis wird zurückgegeben.

Wie bereits erwähnt, ist dies das Standardverhalten. Es steht einem frei, das Protokoll durch erneute Implementierung zu ändern __getattribute__.

Diese Technik ist viel leistungsfähiger als Dekorateure.

Giorgi
quelle
6

Ruby verfügt über eine integrierte Unterstützung für die Fortsetzung callcc.

Daher können Sie coole Dinge wie den Amb-Operator implementieren

Dario
quelle
Ich wünschte, ich hätte callcc verstanden. Können Sie ein profaneres Anwendungsszenario als McCarthys Ambiguous Operator angeben, um seine Vorteile zu würdigen? Ich meine etwas Reales, nicht dieses funky CS-Zeug?!
ThomasH
"Funky CS stuff" ist echt. Nehmen Sie sich etwas Zeit zum Lernen: intertwingly.net/blog/2005/04/13/Continuations-for-Curmudgeons
Stephen Eilert
6

Zu diesem Zeitpunkt bietet Python noch eine bessere Unicode-Unterstützung

John La Rooy
quelle
5

Python hat Docstrings und Ruby nicht ... Oder wenn nicht, sind sie nicht so einfach zugänglich wie in Python.

Ps. Wenn ich falsch liege, bitte hinterlassen Sie ein Beispiel. Ich habe eine Problemumgehung, die ich ganz einfach in Klassen einordnen könnte, aber ich hätte gerne eine Art Docstring-Funktion auf "native Weise".

Rasjani
quelle
3
hat keinen Docstring, aber RDoc. Also ja, nicht so leicht zugänglich, aber nicht 100% versteckt.
Omar Qureshi
Ruby verwendet keine Docstrings. Die Dokumentation erfolgt auf andere Weise.
Chuck
1
Omar: Ja, ich kenne rdoc, aber afaik, sie sind nicht "so zugänglich" wie Pythons Docstrings. Wenn ich zum Beispiel eine Klasse habe und die rdoc-Dokumentation aus der Klasse heraus ausgeben möchte, ist das eine ziemlich schwere Aufgabe. Was ich getan habe, ist, dass ich eine RI-Dokumentation generiere, die ich versuche, auf dem neuesten Stand zu halten und diese Informationen dann selbst abzurufen. Auf jeden Fall nicht auf dem gleichen Niveau wie Pythons Docstrings.
Rasjani
Docstrings können verwendet werden, um Doctests bereitzustellen. Gibt es so etwas für Ruby?
Lennart Regebro
2
Ja, es heißt "Ruby Doctest". Was Doktrinen betrifft, ist alles, was wirklich wichtig ist, dass Sie irgendwo lesbare Dokumentation haben, die testbare Codefragmente enthält - es macht keinen Unterschied, ob es sich um eine Dokumentzeichenfolge oder einen Kommentar handelt.
Chuck
5

Ruby hat eine zeilenweise Schleife über Eingabedateien (das '-n'-Flag) über die Befehlszeile, sodass es wie AWK verwendet werden kann. Dieser Ruby Einzeiler:

ruby -ne 'END {puts $.}'

zählt Linien wie der AWK Einzeiler:

awk 'END{print NR}'

Ruby erhält dieses Feature durch Perl, das es von AWK übernommen hat, um Sysadmins mit Perl an Bord zu bringen, ohne die Art und Weise ändern zu müssen, wie sie Dinge tun.

Pinochle
quelle
1
Ich möchte hinzufügen, dass die Befehlszeilenunterstützung von Python eher schwach ist. Neben der fehlenden automatischen Schleife können Sie nicht einige Anweisungen in eine einzelne Zeile einfügen und als Befehlszeilenargument mit einer Zeichenfolge an den Interpreter übergeben. Zumindest habe ich das versäumt.
ThomasH
Natürlich kannst du. Aber Sie müssen (wie bei jeder anderen Sprache) in Anführungszeichen setzen.
Lennart Regebro
Python ist nicht für die Verwendung in der Befehlszeile vorgesehen, da Sie einige Dinge (wie sys.stdin) explizit angeben müssen, wenn Sie es auf diese Weise verwenden python -c "import sys; print len(list(sys.stdin))"
möchten
5

Ruby hat Siegel und Zweige, Python nicht.

Edit : Und eine sehr wichtige Sache, die ich vergessen habe (schließlich war die vorherige nur ein wenig zu flammen :-p):

Python hat einen JIT-Compiler ( Psyco ), eine deutlich niedrigere Sprache zum Schreiben von schnellerem Code ( Pyrex ) und die Möglichkeit, Inline-C ++ - Code ( Weave ) hinzuzufügen .

fortran
quelle
Stimmt, aber das ist nur Syntax.
Lennart Regebro
6
Nun, wenn Sie diesen Weg gehen wollen: Beide sind Turing-vollständig. Alles andere ist nur Syntax.
Jörg W Mittag
Ja und ein Unterschied in der Importax-Syntax ;-)
fortran
1
Wie ist es wichtig, wenn Sie @foo oder self.foo schreiben?
Lennart Regebro
1
@ Jörg: OK, nenne es dann etwas anderes als "Syntax". Der Punkt ist, dass @foo und self.foo dasselbe tun, es ist eigentlich keine Funktionalität, die Ruby hat und Python nicht.
Lennart Regebro
5

Meine Python ist rostig, daher sind einige davon möglicherweise in Python und ich erinnere mich einfach nicht / habe sie überhaupt nicht gelernt, aber hier sind die ersten, an die ich gedacht habe:

Leerzeichen

Ruby behandelt Whitespace völlig anders. Für den Anfang müssen Sie nichts einrücken (was bedeutet, dass es keine Rolle spielt, ob Sie 4 Leerzeichen oder 1 Tabulator verwenden). Es wird auch eine Smart Line-Fortsetzung durchgeführt, sodass Folgendes gültig ist:

def foo(bar,
        cow)

Wenn Sie mit einem Operator enden, wird im Grunde herausgefunden, was los ist.

Mixins

Ruby hat Mixins, die Instanzen anstelle vollständiger Klassen erweitern können:

module Humor
  def tickle
    "hee, hee!"
  end
end
a = "Grouchy"
a.extend Humor
a.tickle    »   "hee, hee!"

Aufzählungen

Ich bin mir nicht sicher, ob dies dasselbe ist wie bei Generatoren, aber ab Ruby 1.9 Ruby als Aufzählung

>> enum = (1..4).to_enum
=> #<Enumerator:0x1344a8>

Referenz: http://blog.nuclearsquid.com/writings/ruby-1-9-what-s-new-what-s-changed

"Schlüsselwortargumente"

Beide dort aufgelisteten Elemente werden in Ruby unterstützt, obwohl Sie solche Standardwerte nicht überspringen können. Sie können entweder in der richtigen Reihenfolge gehen

def foo(a, b=2, c=3)
  puts "#{a}, #{b}, #{c}"
end
foo(1,3)   >> 1, 3, 3
foo(1,c=5) >> 1, 5, 3
c          >> 5

Beachten Sie, dass c = 5 der Variablen c im aufrufenden Bereich tatsächlich den Wert 5 zuweist und den Parameter b den Wert 5 setzt.

oder Sie können es mit Hashes tun, die das zweite Problem beheben

def foo(a, others)
  others[:b] = 2 unless others.include?(:b)
  others[:c] = 3 unless others.include?(:c)
  puts "#{a}, #{others[:b]}, #{others[:c]}"
end
foo(1,:b=>3) >> 1, 3, 3
foo(1,:c=>5) >> 1, 2, 5

Referenz: Der Pragmatic Progammer's Guide to Ruby

Scott Dugas
quelle
Ihr zweites Beispiel foo (1, c = 5) macht nicht das, was Sie denken. Ruby hat keine benannten Parameter.
Horseyguy
5
Python hat implizite Fortsetzungszeile Klammern innen (, [oder{
u0b34a0f6ae
5

Sie können Code in der Klassendefinition sowohl in Ruby als auch in Python haben. In Ruby haben Sie jedoch einen Verweis auf die Klasse (self). In Python haben Sie keinen Verweis auf die Klasse, da die Klasse noch nicht definiert ist.

Ein Beispiel:

class Kaka
  puts self
end

Selbst in diesem Fall ist die Klasse, und dieser Code würde "Kaka" ausdrucken. Es gibt keine Möglichkeit, den Klassennamen auszudrucken oder auf andere Weise über den Klassendefinitionskörper in Python auf die Klasse zuzugreifen.

Lennart Regebro
quelle
Können Sie weitere Details (wie Code) für Ihren ersten Punkt angeben?
Loïc Wolff
Beispielcode ist eine gute Idee, das habe ich hinzugefügt, obwohl dieser Fall trivial ist.
Lennart Regebro
@ SilentGhost: Ich kann mir keine vorstellen, die momentan nicht wirklich dunkel ist. :)
Lennart Regebro
Sie können auf den Klassennamen innerhalb der Klasse in Python zugreifen: class foo (): def init __ (self): print self .__ class .__ name__
txwikinger
1
@txwikinger: Ja, aber nicht innerhalb des Körpers der Klasse, der gleichzeitig mit der classAnweisung ausgeführt wird.
Bastien Léonard
4

Syntax ist keine Kleinigkeit, sie hat direkten Einfluss darauf, wie wir denken. Dies wirkt sich auch direkt auf die Regeln aus, die wir für die von uns verwendeten Systeme erstellen. Als Beispiel haben wir die Reihenfolge der Operationen aufgrund der Art und Weise, wie wir mathematische Gleichungen oder Sätze schreiben. Die Standardnotation für Mathematik ermöglicht es den Menschen, sie auf mehrere Arten zu lesen und mit derselben Gleichung zu unterschiedlichen Antworten zu gelangen. Wenn wir die Präfix- oder Postfix-Notation verwendet hätten, hätten wir Regeln erstellt, um zu unterscheiden, welche Zahlen manipuliert werden sollen, anstatt nur Regeln für die Reihenfolge zu haben, in der Werte berechnet werden sollen.

Die Standardnotation macht deutlich, um welche Zahlen es sich handelt, während die Reihenfolge, in der sie berechnet werden sollen, nicht eindeutig ist. Die Präfix- und Postfix-Notation machen die Reihenfolge der Berechnung einfach, während die Zahlen mehrdeutig sind. Python hätte bereits mehrzeilige Lambdas, wenn es nicht die Schwierigkeiten gäbe, die durch das syntaktische Leerzeichen verursacht werden. (Es gibt Vorschläge, diese Art von Dingen durchzuziehen, ohne unbedingt explizite Blocktrennzeichen hinzuzufügen.)

Ich finde es einfacher, Bedingungen zu schreiben, bei denen ich möchte, dass etwas passiert, wenn eine Bedingung falsch ist, viel einfacher mit der if-Anweisung in Ruby zu schreiben als beispielsweise mit der semantisch äquivalenten "if-not" -Konstruktion in Ruby oder anderen Sprachen. Wenn die meisten Sprachen, die heutzutage verwendet werden, gleich leistungsfähig sind, wie kann die Syntax jeder Sprache als trivial angesehen werden? Nach bestimmten Merkmalen wie Blöcken und Vererbungsmechanismen usw. ist die Syntax der wichtigste Teil einer Sprache, kaum eine oberflächliche Sache.

Oberflächlich sind die ästhetischen Qualitäten der Schönheit, die wir der Syntax zuschreiben. Ästhetik hat nichts damit zu tun, wie unsere Erkenntnis funktioniert, Syntax.

Schattenfertigkeit
quelle
Dieser "Kommentar" ist dreimal so lang wie in einem Kommentar zulässig, unabhängig von der Wiederholung.
Andrew Grimm
Dies scheint mir als Antwort in Ordnung zu sein. Das Bit "Dies ist ein Kommentar" wurde herausgeschnitten.
Bill the Lizard
3

Überrascht zu sehen, dass nichts von Rubys "Methode fehlt" -Mechanismus erwähnt wird. Ich würde Beispiele für die find_by _... -Methoden in Rails als Beispiel für die Leistungsfähigkeit dieser Sprachfunktion geben. Ich vermute, dass etwas Ähnliches in Python implementiert werden könnte, aber meines Wissens ist es nicht nativ vorhanden.

MikeIsGo
quelle
Python hat get_attribute , was im Grunde das Gleiche wie Rubys method_missing bewirkt.
Mipadi
3
Warum werden Python-Entwickler immer so verletzt, wenn Rubin ÜBERALL erwähnt wird? Sie können nicht leugnen, dass dies nicht wahr ist.
Aarona
method_missingkann in einigen Fällen in Python emuliert werden : class M(): def __getattr__(self, n): return lambda: "Missing! " + n; M().hi(). Es gibt jedoch geringfügige Unterschiede und ich bezweifle, dass es in Python idiomatisch ist :-)
1
@DJTripleThreat: Ich leugne, dass es wahr ist.
Lennart Regebro
3

Ein weiterer Unterschied bei Lambdas zwischen Python und Ruby zeigt das Problem des Akkumulatorgenerators von Paul Graham . Hier abgedruckt:

Schreiben Sie eine Funktion foo, die eine Zahl n annimmt und eine Funktion zurückgibt, die eine Zahl i annimmt, und n zurückgibt, das um i erhöht ist. Hinweis: (a) das ist eine Zahl, keine ganze Zahl, (b) das ist erhöht um, nicht plus.

In Ruby können Sie Folgendes tun:

def foo(n)
  lambda {|i| n += i }
end

In Python würden Sie ein Objekt erstellen, das den Status von n enthält:

class foo(object):
    def __init__(self, n):
        self.n = n
    def __call__(self, i):
        self.n += i
        return self.n

Einige Leute bevorzugen möglicherweise den expliziten Python-Ansatz, da er konzeptionell klarer ist, auch wenn er etwas ausführlicher ist. Sie speichern den Status wie für alles andere. Sie müssen sich nur um die Idee von aufrufbaren Objekten kümmern. Unabhängig davon, welchen Ansatz man ästhetisch bevorzugt, zeigt er einen Respekt, in dem Ruby Lambdas mächtigere Konstrukte sind als Pythons.

Wohnheimbee
quelle
3
Sie können in Python keine Zahlen erhöhen, sodass eine Einschränkung keinen Sinn ergibt. In Python sind Zahlen unveränderlich. Wenn wir es stattdessen in "plus" ändern, ist die Klasse nicht erforderlich. Daher zeigt dies nichts über den Lambda-Unterschied, sondern den Unterschied in der Funktionsweise von Zahlen. Es sei denn, Sie erstellen eine veränderbare Zahlenklasse. :)
Lennart Regebro
2
Die Einschränkung dient dazu, das gewünschte Verhalten zu verdeutlichen. Was das Problem verlangt, ist: f = foo (10) f (2) >> 12 f (3) >> 15 ... lambda {| i | n + i} ergibt: f = foo (10) f (2) >> 12 f (3) >> 13 ... Zahlen sind auch in Ruby unveränderlich - man kann zum Beispiel nicht 2 + = 1 sagen. Und n + = 1 ist in einer regulären Python-Funktion in Ordnung, aber kein Lambda. Es kommt also darauf an, was "n" ist, dass es erstellt wird, wenn die Funktion aufgerufen und das Lambda gebildet wird, dass Sie eine Zuweisung in einem Lambda vornehmen können (anstatt nur Ausdrücke) und dass es den Wert von n enthalten kann über mehrere Anrufe.
Wohnheimbee
Ich glaube nicht, dass Sie in Python so weit gehen müssen. Funktionen können in anderen Funktionen definiert werden.def foo(n): def f(i): return n + i return f.
FMc
2
Es ist jedoch immer noch nicht dasselbe, und Ihr Beispiel entspricht dem Python-Lambda im obigen Kommentar. Die Ruby-Version erstellt ein Lambda, das den Status zwischen den Aufrufen beibehält. In dem von Ihnen veröffentlichten Beispiel können Sie einen Startwert für n konfigurieren, aber die von foo zurückgegebene Funktion hat immer diesen Startwert. Die Ruby-Version wird inkrementiert. Sagen wir also f = foo (10). Die Python-Version: f (1) => 11, f (1) => 11. Die Ruby-Version f.call (1) => 11, f.call (1) => 12.
dormsbee
def foo(n): L=[n] def f(i): L[0] += i return L[0] return f. In Python3 können Sie ein nonlocalSchlüsselwort verwenden.
JFS
3

Python hat optionale Argumente benannt

def func(a, b=2, c=3):
    print a, b, c

>>> func(1)
1 2 3
>>> func(1, c=4)
1 2 4

AFAIK Ruby hat nur Argumente positioniert, da b = 2 in der Funktionsdeklaration eine Beeinflussung ist, die immer angehängt wird.

Batiste Bieler
quelle
3
Was bedeutet "Ruby hat nur Argumente positioniert, weil b = 2 in der Funktionsdeklaration eine Beeinflussung ist, die immer angehängt wird" überhaupt?
Horseyguy
3
Keine Ahnung, auf welchem ​​Planeten du lebst, aber def my_method(param1, optional = false)funktioniert in Ruby 1.8.6, 1.8.7 und vermutlich 1.9!
Robert K
5
Der böse Floh und die Leute, die seinen Kommentar positiv bewertet haben, haben Sie sich das Beispiel nicht genau genug angesehen. Er kann den bParameter im funcAufruf überspringen und er behält seine Standardeinstellung bei. Das heißt, es bist das zweite Argument in der Signatur, aber er kann es überspringen, indem er dem zweiten Parameter das Präfix vorstellt c=. Ruby verwendet Hashes, um dies zu simulieren, aber es ist nicht genau dasselbe.
Maček
2

Ruby hat Dokumentation eingebettet:

 =begin

 You could use rdoc to generate man pages from this documentation

 =end
ko-dos
quelle
5
Die Dokumentzeichenfolgen sind Teil der Methoden / Klassen, für die Sie sie festgelegt haben. Sie können also helfen (Klasse) und es zeigt Ihnen die Docstrings usw.
Lennart Regebro
2

Wenn Sie in Ruby eine Datei mit require importieren, landen alle in dieser Datei definierten Elemente in Ihrem globalen Namespace.

Mit Cargo können Sie " Bibliotheken benötigen, ohne Ihren Namespace zu überladen ".

# foo-1.0.0.rb
class Foo
  VERSION = "1.0.0"
end

# foo-2.0.0.rb
class Foo
  VERSION = "2.0.0"
end
>> Foo1 = importieren ("foo-1.0.0")
>> Foo2 = importieren ("foo-2.0.0")
>> Foo1 :: VERSION
=> "1.0.0"
>> Foo2 :: VERSION
=> "2.0.0"
Jonas Elfström
quelle
Dies sollte eher ein Kommentar sein, keine neue Antwort.
Lennart Regebro