Unterschiede zwischen "Java OOP" und "Pythonic OOP"? [geschlossen]

19

Ich habe mit ActionScript 2.0 begonnen und bin dann mit Java weitergegangen. Ich habe seitdem eine Reihe von Sprachen gelernt oder zumindest benutzt, einschließlich Python (wahrscheinlich mein Favorit).

Ich befürchte jedoch, dass mein Stil der objektorientierten Programmierung sehr unpythonisch ist und eher Java OOP mit Python-Syntax ähnelt. Was unterscheidet Java von Pythonic OOP? Was machen Java-Programmierer oft "unpythonisch", wenn sie objektorientierten Code in Python schreiben?

Anto
quelle

Antworten:

54

Für einen Java-Typ ist Python ein anarchischer Spielball, bei dem sich jeder einen Schläger schnappen und anfangen kann, den Kopf zu zertrümmern.

Für einen Python-Typ ist Java ein orwellsches Universum, in dem Sie ständig an die abnehmende Sichtweise eines anderen gefesselt sind, wie das Universum tickt.

Die Wahrheit ist alles, was Sie in einer Sprache tun können, die Sie in der anderen genauso sauber tun können. Wie Sie bereits erwähnt haben, gibt es in beiden Gemeinden wichtige Unterschiede, was sauber bedeutet.

Java-Methode: Ein sauberes System ist ein System, das das tut, was beabsichtigt ist, und nichts anderes. Es lässt keine Erweiterungen oder Änderungen zu, die der Art des beabsichtigten Zwecks zuwiderlaufen, und versucht, diese durch den Compiler so weit wie möglich durchzusetzen. Flexibilität wird durch sorgfältige Bearbeitung einfacher Schnittstellen innerhalb strenger Strukturen erreicht. In Java sollte die Sandbox immer klar abgegrenzt sein und das Überschreiten sollte schnelles Feedback vom Compiler erhalten. Java bietet die Möglichkeit , Objektstrukturen statisch zu definieren und aus diesen Instanzen dynamische Interaktionen zu erstellen. Wenn ich in Java arbeite, versuche ich geschickt, grundlegende Bausteine ​​für eine gehirntote Lösung zu erstellen. Ich arbeite meistens von unten nach oben, sobald ich eine Arbeitstheorie zur Lösung des Problems habe.

Java wird in der Regel große Software produzieren, die große Teams umfassen kann, und Tools und Mittel bereitstellen, um die Herde in Schach zu halten. Wenn das Kontrollkästchen deaktiviert bleibt, werden sehr getrennte Teams eigenständig auf ein immer unklareres Ziel hinarbeiten. Irgendwann wird jedes Team zu einer "raison d'être" und das System als Ganzes wird verwässert, wenn man vom Hauptprojekt abweicht. Dies kann zu extremen Kostenüberschreitungen und riesigen Softwaresystemen führen, die schlecht funktionieren und gewartet werden.

In Java gibt es so gut wie keine einfache und schnelle Möglichkeit, Dinge zu erledigen, aber die IDE und das Tool sind dazu da, schmerzhafte Aufgaben mit nur wenigen Klicks zu erledigen.

Python-Methode: Sauber heißt, kurz und gut lesbar. Ein gutes Python-System wurde entwickelt, um Sie auf den Punkt zu bringen und die innersten Geheimnisse aufzudecken, so dass Sie anhand des Codes den beabsichtigten Gebrauch und Zweck verstehen können. Sie können damit auch Ihre eigene Lösung entwerfen, indem Sie das ursprüngliche Design so erweitern und / oder einkapseln, dass es genau in Ihre Richtung verläuft. Mit Python können Sie Objektvorlagen erstellen, aus denen Sie die Instanz dynamisch an die jeweiligen Anforderungen anpassen können. In Python neige ich dazu, das Problem sofort anzugehen und dann den Code in einer logischen Struktur zu verbreiten, sodass die endgültige Lösung so einfach und lesbar wie möglich bleibt. In Python neige ich dazu, von oben nach unten zu arbeiten und die zunehmenden Komplexitäten durch einen Divide-and-Conquer-Ansatz zu managen.

Python-Teams tendieren dazu, leichte Systeme zu produzieren und liefern sehr schnell eine funktionierende Lösung. Sie sind in der Regel eng miteinander verbunden und arbeiten austauschbar an jedem Teil des Systems, um bei jeder Gelegenheit die gegenseitige Lösung zu validieren. Sie nähren sich gegenseitig und schaffen eine Synergie, die ziemlich berauschend ist. Dadurch entstehen jedoch Teams, die sich nur schwer auf größere Systeme skalieren lassen und häufig an eine Art Glasdecke stoßen. Die Einführung neuer Mitglieder in das Team wird helfen, aber es wird einige Zeit dauern, bis sich das Wissen so weit verbreitet hat, dass die zusätzliche Produktivität spürbar wird. Das Team wird dann geteilt und der ständige Überblick über das gesamte System sowie die Atmosphäre der frühen Tage werden verwässert. Dies kann zu übermäßig verschlungenem Code führen, was früher ein einfaches Problem war.

Es gibt fast immer eine schnelle und einfache Möglichkeit, Dinge mit Python zu erledigen, aber es kann schwieriger sein, die Komplexität zu kontrollieren, sobald das System einen bestimmten Schwellenwert erreicht.

Kurz gesagt, beide haben eine dunkle Seite und beide haben eine klare Stärke. Wenn Sie jedoch entlang beider Gemeinschaften stapfen, werden Sie feststellen, dass die Stärke der einen zur dunklen Seite der anderen führt und umgekehrt.

Daher die hitzigen Debatten darüber, welches das Beste ist.

Newtopian
quelle
14

Sie wissen also, wie man die Sichtbarkeit von Methoden und Variablen einstellt? Ja, die gibt es nicht mehr, alles ist öffentlich. Es gibt Namenskonventionen und Namensmanipulationen, aber alles ist wirklich noch verfügbar.

Ein Teil der Flexibilität von Python beruht auf der Tatsache, dass Sie fast alles tun dürfen. Aus diesem Grund ist die Philosophie, dass die Benutzer wissen sollten, wie sie die API verwenden, anstatt dass die API die ordnungsgemäße Verwendung einer Methode erzwingt.

Anstelle von Methodenüberladungen haben Sie Standardvariablen. Verwenden Sie keine veränderlichen Objekte als Standardwert.

# bad
def fL(x=[])
  x.append(1)
  print x
# good
def fN(x=None)
  if (x is None):
    x = []
  x.append(1)
  print x

fL()
fL()
fN()
fN()

Der Unterschied zwischen Klassen- und Instanzvariablen ist beim ersten Start sehr subtil.

class Obj(object):
   thing = "class variable"
   def __init__(self):
      self.thing1 = "instance variable"
      print self.thing, self.thing1

Das sind einige der Dinge, an die ich mich gewöhnen musste, als ich den Wechsel vollzogen habe.

unholysampler
quelle
1
+1 gute Zusammenfassung einiger Dinge, obwohl ich die von
vorhin
6

Nun, Python hat keine Schnittstellen, hat Metaklassen und erlaubt das Eingeben von Enten. Python hat Listenverständnisse, die sehr mächtig sind und in Java nicht existieren. Java hat ein reichhaltiges Typensystem mit vielen Datenstrukturen, und Python hat nur Listen. Wenn Sie also die Vorteile von Python nutzen, anstatt zu versuchen, die Java-Funktionen in Python wiederherzustellen, schreiben Sie wahrscheinlich Pythonic-Code.

Was den OO-Code angeht, gibt es bestimmte Stilgrundlagen, die sich nicht von Sprache zu Sprache ändern sollten: Sie sollten immer versuchen, schüchternen und trockenen Code zu schreiben, unabhängig davon, ob Sie in Applescript, Python, Java oder C ++ schreiben.

----Bearbeiten----

Wie @delnan pedantisch betont, gibt es tatsächlich FÜNF zusammengesetzte Datentypen, die von Python auf Kernel-Ebene definiert wurden (Liste, Diktat, Tupel, Menge und Frozenset gemäß meiner Kopie von "Python in a Nutshell"). Obwohl dies zutrifft, ist es für den Punkt, den ich anstrebe, eigentlich nicht relevant: Python baut auf Listen als wesentliche Datenstruktur auf. Ja, Sie können eine Liste als Stapel verwenden, aber Sie können genau dieselbe Liste als Warteschlange verwenden. Und dann nochmal einen Stapel.

Java hat andererseits eine Kerneldatenstruktur (Array, gemäß "The Java Pocket Guide"), aber im Allgemeinen können Sie in Java nicht viel erreichen, ohne Sammlungen zu importieren. Sobald Sie dies tun, haben Sie Zugriff zu einer 'reichen' (in welchem ​​Sinne ich immens komplexen) Typbibliothek, mit der Sie die gleiche Funktionalität erhalten, die Sie mit Pythons Liste hatten.

Natürlich haben beide Sprachen Klassen und Java Schnittstellen, aber obwohl es sich um zusammengesetzte Datentypen handelt, handelt es sich nicht wirklich um Datenstrukturen im Sinne eines Lehrbuchs.

Ein Unterschied besteht darin, dass Sie ein Element nicht aus einer Java-Warteschlange entfernen und ein Java-Warteschlangenobjekt nicht an einen Ort übergeben können, an dem eine Java-verknüpfte Liste erwartet wird. Also vielleicht mit "reich" meine ich eigentlich "starr".

Um zu erklären, was ich mit "Python hat nur Listen" meine, meine ich, dass Sie in Python so ziemlich alles tun können, was Sie mit Java-Sammlungen mit dem Typ "Pythons-Liste" tun würden. Dieser einzelne Typ erledigt die Arbeit vieler Typen in Java.

Was bedeutet das für den Python-Programmierer? Dies bedeutet, dass Sie den Python-Listentyp nutzen können, um sehr markanten, direkten Code ohne die Verwendung zusätzlicher Bibliotheken zu schreiben - und die Markigkeit (dh die Eigenschaft, mehr Wert in weniger Zeichen zu übermitteln) ist ein Kernmerkmal von "Pythonic" -Code .

philosodad
quelle
Ich kenne alle außer Metaklassen und werde sie nachschlagen. Vielen Dank :)
Anto
7
-1, bis Sie Folgendes erklären können: (1) "Python hat nur Listen" - Python hat eine Fülle von Datenstrukturen. Es gibt nicht drei Implementierungen für jede einzelne Datenstruktur, die jemals konzipiert wurde, aber dennoch für jede, die die meisten Menschen jemals benötigen werden. (2) Javas Typsystem als "reich" zu bezeichnen, ist ein Hohn dieser wirklich hoch entwickelten Typsysteme. Für den Anfang , Blick auf Haskell (98 ohne Erweiterungen).
Es tut mir leid, das ist einfach nicht wahr. Python hat genau zwei Datenstrukturen: Listen und Wörterbücher. Einige Python-BIBLIOTHEKEN erweitern möglicherweise diese Kernstrukturen, aber das ist nicht dasselbe wie zu sagen, dass die Sprache sie hat.
Philosodad
5
Das sind schon doppelt so viele wie die Antwortnamen. Die Liste dient gleichzeitig als Stapel. Auch Mengen und Tupel sind integriert (wie viele Datenstrukturen sind in Java integriert?). Die Standardbibliothek enthält auch Module für (Min-) Heaps, Deques, unveränderliche Datensätze und dicht gepackte homogene Arrays (beschränkt auf C) Typen). Und das ist nur von oben. Ja, die meisten verwenden Listen / Dikte intern (Sets sind jedoch keine Dikte mit nicht verwendeten Schlüsseln). Aber so sind die meisten Sammlungen in Java - tatsächlich in allen Sprachen. So funktioniert das.
1
Jetzt denke ich, ich verstehe den Punkt, den Sie versucht haben (und habe meine Ablehnung entfernt - die ich an erster Stelle hinzugefügt habe, weil dieser Teil eindeutig falsch war, wie er ursprünglich angegeben wurde). Ich denke immer noch, dass Sie mindestens zwei Datenstrukturen berücksichtigen müssen (Listen als fast universelle Sequenzen und Dikte als fast universelle Zuordnungen). Ganz zu schweigen von den verschiedenen Iteratoren und Generatoren, die ich mindestens so (und wahrscheinlich noch häufiger) als Listen verwende.