Frage zur OOP in Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

orossum hat geschrieben:Das ganze hat natürlich in der Ausgabe 3 resultiert. Nur war myVar danach 3. Mein Lehrer hat mir darauf gesagt das ich der Funktion auf irgenteine Art und weise den Zeiger auf die variable mitgebe, und sie deshalb auch global verändert wird. Deshalb habe ich das Ganze dann in etwa so versucht:
Das Beispiel ist äußerst schlecht gewählt! "myVar" wird niemals den Wert 3 annehmen. Was dein Lehrer offensichtlich nicht verstanden hat ist, dass in Python niemals Kopien erzeugt werden, sondern immer Referenzen übergeben werden.

Code: Alles auswählen

>>> def add(a, b):
...     print a, b
...     a += b
...     print a, b
...
>>> x, y = 1, 2
>>> add(x, y)
1 2
3 2
>>> print x, y
1 2
>>> x, y = [1, 2, 3], [4, 5, 6]
>>> add(x, y)
[1, 2, 3] [4, 5, 6]
[1, 2, 3, 4, 5, 6] [4, 5, 6]
>>> print x, y
[1, 2, 3, 4, 5, 6] [4, 5, 6]
Das Leben ist wie ein Tennisball.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

orossum hat geschrieben:Die Funktion bearbeitet im echten Skript aber einen assoziativen Array anstatt einem Integer, ich nehme an das könnte auch helfen.
Das oben genannte Beispiel funktioniert einwandfrei (zumindest bei mir Zuhause, neueste Python-Version), ich hab es hier nur als Beispiel hinzugefügt.
Uhh, mit einem Dictionary ist das aber etwas *ganz* anderes. Ich tippe mal auf sowas

Code: Alles auswählen

In [3]: def increment(var, key): var[key] = var[key] + 1
   ...: 

In [4]: foo = {"bar": 2}

In [5]: increment(foo, "bar")

In [6]: print foo
{'bar': 3}
Wie man unschwer erkennt ist var[key] = var[key] + 1 schon rein optisch etwas anderes als var = var + 1. Beim ersteren veränderst du das Objekt auf das var zeigt(var[key] = x entpricht einem var.__setitem__(key, x)), beim zweiten weist du der Variable var einen neuen Wert zu.

Um das noch einmal klar zustellen, Python übergibt immer Zeiger/(Java-)Referenzen an Funktionen, da wird kein Objekt kopiert.

PS: Interessant wie manche hier abgehen, wenn ein Hauch von Kritik an Python zu erkennen ist.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

An dieser Stelle möchte ich einmal auf PEP 8 verweisen (mein Lehrer hälts auch nicht ein) und auf das offzielle Tutorial.

Da sollte doch der Unterschied zwischen mutable und immutable behandelt werden, oder?
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Doch nicht so guter Lehrer ...

Euer Lehrer hat offenbar Grundlegendes des Python-Sprachkonzepts nicht verstanden - das kann er euch natürlich dann auch nicht vermitteln. Heraus kommt dann so etwas wie dein Beispiel der "unerklärlichen Veränderung". Dass das so, wie du es zeigst, nicht sein kann, wurde dir schon gesagt. Bei einem "assoziativen Array" (in Python heißt das Dictionary) ist das eine ganz andere Geschichte. Mit immutable/mutable hat das allerdings nichts zu tun, sondern mit der Bindung von Objekten an Namen/Bezeichner.

Die private/public-Geschichte ist in Python hervorragend gelöst - viel besser als z.B. in Java. Dieser ganze Setter-/Getter-Kram und die Angst, es könnte jemand auf ein privates Attribut zugreifen ... da genügt eine gute Konvention wie in Python zur Kennzeichnung von als privat gedachten Attributen völlig: "Ein führender Unterstrich = lass mich in Ruhe". Wer sich nicht dran hält: Selbst Schuld.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

numerix hat geschrieben: Mit immutable/mutable hat das allerdings nichts zu tun, sondern mit der Bindung von Objekten an Namen/Bezeichner.
Ja/Nein. Du hast Recht.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
BlackJack

@orossum: Mich würde bei Listen mit hohen Indizes mal interessieren was da mit der Performance nicht stimmt!?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich finds interessant dass man inzwischen im Informatikunterricht mit großen n umgeht bei der man die Unterschiede zwischen den Komplexitätsklassen spürt :)

Schlechte Performance bei hohen Indices finde ich auch etwas seltsam, da der Indexzugriff auf Listen in Python O(1) sein sollte.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Es gibt hier immer mal mehr oder weniger heftige Diskussionen über Vor- und Nachteile oder Defizite von Python. Die meisten Diskusionen konvergieren immer gegen "Es ist gut so wie es ist". Finde ich ein bißchen schade.
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

hendrikS hat geschrieben:Es gibt hier immer mal mehr oder weniger heftige Diskussionen über Vor- und Nachteile oder Defizite von Python. Die meisten Diskusionen konvergieren immer gegen "Es ist gut so wie es ist". Finde ich ein bißchen schade.
Das könnte daran liegen, daß die Leute, die wirkliche Probleme damit haben, es schlicht nicht nutzen. Und Nicht-Nutzer wirst du hier in diesem Forum wohl eher nicht finden. Da müßte man eher mal auf Stackoverflow oder an einer ähnlichen "mehrsprachigen" Stelle eine entsprechende Diskussion anstoßen.
Nocta
User
Beiträge: 290
Registriert: Freitag 22. Juni 2007, 14:13

Das ist doch ein toller Thread.
Man findet hier bestimmt sämtliche wichtige Gründe, weshalb Python am Anfang oft nicht verstanden wird :)
Ich (und viele andere bestimmt auch) hatte auch mal eine Phase, wo ich mir dachte "Hä? Was für eine komische Sprache, total sinnlos!".
Aber als ich dann hier aufgeklärt wurde, kam mir das Verhalten, das Python aufweist, an vielen Stellen logischer vor, als bei anderen Sprachen.

Gibt es schon sowas wie einen FAQ-Thread zu eben solchen Fragen?
Wenn nicht, könnten wir ja mal diese ganzen "naiven" Behauptungen, wie sie zB der Threadersteller aufstellt, aufschreiben und dagegen argumentieren.
Dann können wir direkt auf diesen Thread verweisen und müssen nicht jedes mal wieder von Vorne anfangen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Nocta hat geschrieben:Gibt es schon sowas wie einen FAQ-Thread zu eben solchen Fragen?
Ja, siehe oben: "Wiki FAQ". Wobei die Adresse momentan diese ist: FAQ.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nocta
User
Beiträge: 290
Registriert: Freitag 22. Juni 2007, 14:13

Dort finde ich aber nicht solche Fragen, wie sie hier besprochen wurden.
  • * Warum self?
    * Private/Public fehlt
    * "unerkläreliche Veränderung" (diese myVar Geschichte)
Und das gehört wohl mit zu den verwirrendsten Dingen in Python.

Oder war das als eine Aufforderung gemeint, das jetzt da rein zu schreiben?
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Nocta hat geschrieben:Oder war das als eine Aufforderung gemeint, das jetzt da rein zu schreiben?
I think so^^
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Nocta hat geschrieben:Oder war das als eine Aufforderung gemeint, das jetzt da rein zu schreiben?
Exakt :) Du wolltest so einen Thread starten und dabei haben wir so eine Seite wo man genau sowas reinschreiben kann.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

orossum, ein weiser Mann hat einmal erkannt: "Ich weiß, dass ich nicht weiß". Die Erkenntnis, dass das eigene Wissen vielleicht nicht richtig ist, ist jedoch das Ergebnis eines Lernprozesses, den, so muss ich aus deinen aggressiven Aussagen (gerade auch in einem anderen Thead) schließen, bei dir noch nicht abgeschlossen ist.

Die Aussage, "Mir ist aufgefallen, dass bei der OOP bei allen Methoden einer Klasse das erste Argument automatisch der Zeiger auf die Klasse selbst ist." ist falsch. Damit sind auch deine Schlussfolgerungen falsch.

Oberlehrermodus an!

Objektorientierung ist eine Vorgehensweise, Probleme in kleine in sich abgeschlossene Einheiten (die Objekte) zu zerteilen und ihr Verhalten (in Form von Methoden) und dann ihre Zusammenarbeit zu beschreiben. Objekte zu klassifizieren ist ein häufig auftretendes, aber nicht immer vorkommendes Merkmal der Objektorientierung. Tatsächlich ist der prototypische Ansatz die reinere Lehre, da man nur ein Konzept - nämlich Objekte - braucht, um es zu erklären.

Smalltalk hat die Idee geprägt, das Objekte zusammenarbeiten, in dem sich sich gegenseitig Nachrichten schicken. Der Empfänger einer Nachricht - in Smalltalk über die Pseudovariable "self" erreichbar (da kommt dieser Name her) - ist ein Objekt - keine Klasse. Und von Zeigern, einem Implementationsdetail, will man in diesem Kontext überhaupt nicht reden.

Schaut man sich an, was bei einem Smalltalk-Ausdruck "object action", den man in Python und vielen anderen Sprachen als "object.action()" schreiben würde, passiert, dann wird aus einer Menge von Funktionen (aka Methoden) namens "action" die passende ausgewählt, indem man eine Auswahlfunktion auf "object" anwendet. Man könnte das genauso "action(object)" oder wie in Lisp "(action object)" schreiben.

Aus Lisp kommt nun die Idee, dass man derartige Funktionen - die dort generische Funktionen heißen, weil sie die Auswahlfunktion sind, die basierend auf ihrem Argument die passende konkrete Funktion (aka Methode) auswählen - also derartige Funktionen nicht nur über ein Argument sondern mehrere oder alle spezialisieren kann. Wird mehr als ein Argument (das nicht notwendigerweise das erste sein muss) für die Auswahl der Methode herangezogen, spricht man hier auch von Multimethoden. Erneut das mächtigere, weil allgemeinere Konzept, wenn auch nicht so verbreitet.

Nix erstes Argument, nix Zeiger, nix Klasse.

In Python hat man sich dafür entschieden, die implizite Pseudovariable, wie sie Smalltalk als "self" kannte und wie sie dann C with Classes als "this" übernommen hat, explizit wie in der Lisp-Tradition zu machen, um zu zeigen, wie es ist, nämlich, dass Klassen eigentlich nur Container für Funktionen sind, die im Kontext von Objekten zu Methoden werden.

Ein "foo.bar()" in Python ist nämlich nur (wie z.B. in Lua das "foo:bar()") syntaktischer Zucker für "Foo.bar(foo)" und man sieht, wie die Klasse "Foo" ein Attribut "bar" hat, in dem eine Funktion steckt, die man dann mit einem Exemplar von "Foo" (was in der Variablen "foo" stecken möge) aufrufen kann.

Das ist kein unvernünftiges Konzept, sondern dem Python-Motto "explizit ist besser als implizit" geschuldet und tatsächlich weniger verwirrend als in Sprachen, wo auf einmal eine "magische" Variable "this", "self" oder "me" im aktuellen Kontext gebunden ist und es noch eine magische implizite Auswahlfunktion gibt. Kann man eigentlich in C++ das "this" auch überschreiben? In Objective-C geht es und das finde ich dann auch nicht gerade verständlich (auch wenn mir der Grund, warum man es können muss, klar ist).

A pro pos Auswahlfunktion: In C++ wird sie ja durch die Implementierung mittels vtable erklärt, doch in anderen Sprachen ist sie deutlich komplexer. Das CommonLisp Object System hat diese (ich glaube als einzige Programmiersprache) sogar wählbar gemacht und so das Metaobjektprotokoll erfunden. In Python verbirgt sich die Funktion in der Art und Weise, wie Properties vererbt werden.

In der Aussage "Ich stufe Python durchaus als eine speziell für Anfänger geeignete Skriptsprache ein" schwingt mit, dass ein Profi (so wie du?) diese dann natürlich nicht mehr benutzt. Tatsächlich schafft es Python als eine der wenigen Sprachen, einfach genug zu sein, dass man auch Anfänger damit nicht überfordert, dennoch aber von den Konzepten so mächtig zu sein, dass sie auch für anspruchsvollere funktionale und objektorientierte Konzepte reicht und die Sprache damit auf dem Profi ein mächtiges Werkzeug ist.

Ein (von dir) erkannter Nachteil ist die fehlende lexikografische Bindung der Variablen (wo übrigens auch C und damit C++ versagen). Man muss allerdings Python als Sprache aus den frühen 80ern zugute halten, dass dieses Konzept erst mit Scheme Ende der 70er richtig verstanden wurde und komplizierter zu implementieren ist, als das einfache zweistufige locals/globals-Verfahren von Python. Und die nur nach Deklaration mittels "global" beschreibbaren Variablen haben noch einen Vorteil: Sie vermiesen einem den leichtfertigen Einsatz globale Variablen, was eigentlich gar nicht so schlecht ist.

Das Objektmodell von Python ist natürlich nicht kaputt, nur weil du es noch nicht verstanden hast. Nachteil ist, dass Python 2.x zwei konkurrierende Modelle mischt und Python 1.x wirklich zu kurz geschossen hat. Mit Python 3.x gibt es aber nur noch das "neue", was seit 2001 neu ist und das entspricht dem von Dylan, einem objektorientiertem Scheme und der ersten Sprache, die eine einfache und funktionierende Linearisierung der Oberklassen bei Mehrfachvererbung hinbekommen haben - etwas, was C++ nie gelungen ist. Somit würde ich unter diesem Aspekt eher C++ als kaputt bezeichnen als Python. Übrigens, Dylan war die Antwort auf das CommonLisp Object System (CLOS) und der Versuch, deren Standardauswahlfunktion für Methoden theoretisch fundiert zu definieren. Python nutzt wie gesagt das selbe Verfahren und im Gegensatz zu Dylan, wo man wissen musste, wie es funktioniert, kann man Python durchaus nach der "method resolution order" fragen (auch wenn das für Properties und nicht Methoden gilt, ist der alte Name von Dylan geblieben), indem man die Klassenmethode "mro" aufruft.

Übrigens, Python kennt Metaklassen, ein mächtiges Konzept, das C++, C# oder Java nie gelernt haben und das ebenfalls von Smalltalk her stammt (weswegen Ruby und Objective-C es auch haben) wobei Pythons Metaklassen sehr vereinfacht sind. Ich weiß nicht genau, woher die Idee stammt, vielleicht auch von Dylan oder von OakLisp, einem sehr frühen objektorientiertem Scheme.

Ob man "public" und "private" als Syntax in einer Sprache braucht, sei dahin gestellt und führt sofort zu dem alten Thema (eine Diskussion, die schon vor 20 Jahren geführt wurde und ob deren ich müde geworden bin) ob statische oder dynamische Typisierung nun das bessere Konzept ist.

Das es "++" und "--" in einer gut entworfenen Sprache nicht geben sollte, weil diese Operationen Seiteneffekte haben und Seiteneffekte wiederum (so nicht zwingend wie bei I/O nötig) zu vermeiden sind, ist ein weiterer Punkt, wo Python tatsächlich richtig liegt und Sprachen wie C (deren Designer es in den 70er Jahren nicht besser wusste) falsch liegen, ist ein anderes Thema.

Und wenn der Informatik-Lehrer ratlos ist, dann würde ich ihm und euch empfehlen, genau diese konkreten Fragen hier zu stellen statt den Generalangriff auf Python zu starten. Ich möchte hier ja einmal erleben, dass jemand schreibt "Hallo, ich bin Informatik-Lehrer der Xten Klasse und habe eine Frage, die im Unterricht aufgetreten ist oder deren Beantwortung ich für die Unterrichtsvorbereitung bräuchte". Ich bin mir sicher, ihm oder ihr würde geholfen werden. Und es würde den Schülern helfen, nicht Halb- und oder Unwissen zu erlernen.

Stefan
Zuletzt geändert von sma am Samstag 13. März 2010, 11:38, insgesamt 1-mal geändert.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

hendrikS hat geschrieben:Es gibt hier immer mal mehr oder weniger heftige Diskussionen über Vor- und Nachteile oder Defizite von Python. Die meisten Diskusionen konvergieren immer gegen "Es ist gut so wie es ist". Finde ich ein bißchen schade.
Ich glaube jeder "Profi" hier wird zugeben, dass Python seine Schwächen hat. Nur wenn falsche Kritik gemacht wird, ist's nich gut zu sagen: "Achso, ja, stimmt."... Weil's einfach nicht stimmt.

Mir gefallen ein paar Sachen nicht so gut an Python. Ich empfinde das ausliefern von ganz kleinen Applikationen (<100kb sollen sie sein) nicht so leicht. Aber dafür gibt's andere Sprachen. Das ist nur ein Beispiel...

Sowas wie foobar2000 könnte man wohl nicht mit Python schreiben. Zu wenig private Menschen in meinem Umfeld haben einen Python intepreter installiert, also sollte man zumindest ein Paket anbieten, wo der intepreter mit dabei oder eine py2exe-Version. Aber das ist nur etwas, was ich selber so empfinde und was auch nur einen kleinen Teil von Applikationen betrifft, im Endeffekt. Es gibt noch ein paar andere Sachen, die mich stören... Aber das ist alles relativ.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

sma hat geschrieben:Oberlehrermodus an!
Oh, wow. Es passiert mir öfter dass ich tagelang nichts interressantes im Forum finde, aber an dieser Stelle möchte ich mich ehrlich Bedanken für diesen Ausflug in die Programmiersprachengeschichte und die Klassifikation Pythons in dieser. Oder mit simplen Worten: Wieder was gelernt 8)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Leonidas hat geschrieben:Oh, wow.
Danke. Bitte gerne :)

Stefan
Antworten