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.
orossum
User
Beiträge: 4
Registriert: Mittwoch 9. Dezember 2009, 19:43

Hi,

Unser Informatik-Lehrer hat sich, da wir viele in der Klasse haben die noch keine Programmiersprachen kennen gelernt haben, dafür entschieden mit uns Python zu programmieren.

Mir ist aufgefallen, dass bei der OOP bei allen Methoden einer Klasse das erste Argument automatisch der Zeiger auf die Klasse selbst ist.

Zum Beispiel:

Code: Alles auswählen

class test:
 def __init__(self):
   blah...
 def TolleFunktion(self,argument1,argument2,argument3,...):
   mehr blah()
Ich verstehe den Sinn dahinter einfach nicht. Alle "vernünftigen" Programmiersprachen die ich bis jetzt kennen gelernt habe, stellen einen Zeiger wie self oder this automatisch in jeder Methode der Klasse zur Verfügung.
Warum dann bei jeder Funktion das Argument self an erster Stelle?
  • Es verwirrt, z.B. bei den Fehlermeldungen
    Es ist unnötig
    Es kostet zeit
Mein Lehrer wusste auch nicht weiter und hat mir deshalb gesagt, dass ich doch hier im Forum nachfragen solle, warum self jeder Funktion als Argument übergeben werden muss.

mfg
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Wenn du

Code: Alles auswählen

import this
eingibst, wirst du einen Satz finden der da lautet: "Explicit is better than implicit". Ich denke, das dürfte die Erklärung dafür sein.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Dadurch wird dies möglich:

Code: Alles auswählen

>>> def repr(obj):
...     return obj.__repr__()
...
>>> class C(object):
...     pass
...
>>> C.repr = repr
>>>
>>> C().repr()
'<__main__.C object at 0x01ECCFB0>'
>>>
siehe: http://www.python-forum.de/topic-19762. ... warum+self
[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: Es ist halt *nicht* unnötig, weil Du ja selbst von Funktionen sprichst. Wenn man Funktionen und Methoden nicht zu verschieden machen möchte, so dass Methoden als Funktionen auf Klassen implementiert werden können, die auf einem Exemplar dann als Funktionen angesehen werden können, bei denen das erste Argument schon an das Exemplar gebunden ist, dann braucht man ein explizites `self`.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Der einzige valide Punkt deiner Beschwerde ist die Verwirrende Fehlermeldung, die soll aber AFAIK veraendert werden.

Wenn dir BJ's Erklaerung nicht ausreicht, solltest du einen Blick in das Tutorial werfen, dort wird bespielsweise auch beschrieben, dass Methoden solange Funktionen sind, bis ein Exemplar erzeugt wird und erst dann wird der erste Parameter mit der Objektreferenz bestueckt. Um das zu verdeutlichen:

Code: Alles auswählen

class SomeClass(object):
    def __init__(self, a):
        self.a = a
    def foo(self):
        print self.a

s = SomeClass("x")
SomeClass.foo(s)
Dein Kommentar zu "vernuenftigen" Sprachen, ist uebrigens disqualifizierend. Die meisten Sprachen die das implizit machen, haben meist ein recht kaputtes Objektmodell oder sind statisch. jbs zeigt z.B. wie man die Klasse dynamisch um Methoden erweitert. Allerdings sollte man dabei 2mal nachdenken, wie gesagt "explicit is better than implicit".
lunar

@cofi: Ach, und "kaputtes Objektmodell" ist jetzt nicht disqualifizierend, sondern ein völlig wertfreies und neutrales Urteil, oder? ;)

Ich glaube ja nicht, dass der OP mit seiner Bemerkung Python disqualifizieren wollte, sonst hätte das betreffende Wort wohl kaum in Anführungszeichen gesetzt. Und selbst wenn, wäre das ernst zu nehmen?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

orossum hat geschrieben:Unser Informatik-Lehrer hat sich, da wir viele in der Klasse haben die noch keine Programmiersprachen kennen gelernt haben, dafür entschieden mit uns Python zu programmieren.
Guter Lehrer!
orossum hat geschrieben:Mein Lehrer wusste auch nicht weiter und hat mir deshalb gesagt, dass ich doch hier im Forum nachfragen solle, warum self jeder Funktion als Argument übergeben werden muss.
Sehr guter Lehrer!
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

lunar hat geschrieben:@cofi: Ach, und "kaputtes Objektmodell" ist jetzt nicht disqualifizierend, sondern ein völlig wertfreies und neutrales Urteil, oder? ;)
Klaaa :) Aber ich meinte eigtl. im Zuge der Diskussion.
lunar hat geschrieben:Ich glaube ja nicht, dass der OP mit seiner Bemerkung Python disqualifizieren wollte, sonst hätte das betreffende Wort wohl kaum in Anführungszeichen gesetzt.
Nein, ich meinte dass er sich selbst disqualifiziert. Dass er Python damit als schlechter als Alternativen einstuft, hat er ja explizit ausgefuehrt ;)
lunar

@cofi: Sag mal, liest Du da nicht ein *bisschen* viel aus dem Beitrag des OP heraus? Ich kann da irgendwie nicht erkennen, dass er Python "schlechter einstuft" und sich so "selbst disqualifiziert" hätte*. Für mich fragt da nur jemand nach dem Sinn des expliziten self, dem die Erfahrung zu einer eigenen Einschätzung fehlt, weil er bisher nur Sprachen mit impliziter "Selbstreferenz" genutzt hat.

* Ich find's ja auch komisch, dass man sich "selbst disqualifiziert", wenn man Kritik an Python äußert. Das zeugt schon von einer gewissen Hybris ;)
orossum
User
Beiträge: 4
Registriert: Mittwoch 9. Dezember 2009, 19:43

Danke schon mal für die vielen Antworten!

Ich möchte hier nur ein paar Sachen klar stellen:

Ich stufe Python durchaus als eine speziell für Anfänger geeignete Skriptsprache ein, mitsamt den daraus folgenden Vor- und Nachteilen. (Über die ihr hier sicher bestens bescheid wisst!)

Kaputtes Objektmodell bei Alternativen - naja.. Wenn man in Bezug nimmt, dass Python (zumindest in der Version die unsere Schule zur Verfügung stellt) einige Lücken aufweist (Public,Private nicht existent, etc.)

Python stehe ich eigentlich recht offen gegenüber, obwohl es, wie sich gezeigt hat, noch einige andere Mängel aufweist. (Zum Beispiel: Performance im Allgemeinen sowie bei Arrays/Listen mit hohen Indizies, seltsame, nicht erklärbare Fehler die bei bestimmten Prozeduren auftreten [gesamte Klasse inklusive Informatik-Lehrer ratlos!], in- und dekrementelle Operatoren - warum auch immer es sie nicht gibt, usw.)

mfg
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

orossum hat geschrieben:Wenn man in Bezug nimmt, dass Python (zumindest in der Version die unsere Schule zur Verfügung stellt) einige Lücken aufweist (Public,Private nicht existent, etc.)
Das wundert mich aber.

Ein Attribut einer Klasse wird dadurch als privat gekennzeichnet, dass der Name mit einem Unterstrich beginnt. Dadurch weiß ein Entwickler, dass diese Attribut nicht von außerhalb verwendet werden sollte. Durch den Interpreter wird das nicht weiter forciert. Python setzt da auf den mitdenkenden und verantwortungsbewussten Programmierer.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

orossum hat geschrieben:Python stehe ich eigentlich recht offen gegenüber, obwohl es, wie sich gezeigt hat, noch einige andere Mängel aufweist. (Zum Beispiel: Performance im Allgemeinen sowie bei Arrays/Listen mit hohen Indizies, seltsame, nicht erklärbare Fehler die bei bestimmten Prozeduren auftreten [gesamte Klasse inklusive Informatik-Lehrer ratlos!], in- und dekrementelle Operatoren - warum auch immer es sie nicht gibt, usw.)
Uiuiuiuiui.

Performance im Allgemeinen. Verglichen womit? Und wo macht sich das im Informatikunterricht bemerkbar?

Für euch inkl. Lehrer nicht erklärbare Fehler als Mangel von Python darzustellen: Mutig!

Inkrementelle/dekrementelle Operatoren? Ich nehme an, du meinst so etwas wie n++ oder inc(n).
Was ist am pythonischen "n += 1" so schlimm?
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

orossum hat geschrieben: Python stehe ich eigentlich recht offen gegenüber, obwohl es, wie sich gezeigt hat, noch einige andere Mängel aufweist. (Zum Beispiel: Performance im Allgemeinen sowie bei Arrays/Listen mit hohen Indizies, seltsame, nicht erklärbare Fehler die bei bestimmten Prozeduren auftreten [gesamte Klasse inklusive Informatik-Lehrer ratlos!], in- und dekrementelle Operatoren - warum auch immer es sie nicht gibt, usw.)
mfg
Ich kann mir ehrlich gesagt nicht vorstellen, daß man Python in der Schule an seine Leistungsgrenzen bringen kann. Gerade auch weil ich Python selbst in der Schule gelernt habe. Ich vermute hier mal dreist und ohne Hintergrundkenntnisse die Wahl einer falschen Datenstruktur bzw. eines nicht-optimalen Algorithmusses. Was die nicht-erklärbaren Fehler angeht, wäre ich doch mal sehr an Beispielen interessiert. Das Informatik-Lehrer bisweilen leider nicht das Maß der Dinge sind, wurde an anderer Stelle hier im Forum schon lang und breit diskutiert. Aber auch gestandene Programmierer sehen sich immer wieder mal in einer Situation, in der sie den Fehler einfach nicht ausmachen können und lange nach der meist recht trivialen Ursache forschen. In der Regel ist es ein Denkfehler ;)
orossum
User
Beiträge: 4
Registriert: Mittwoch 9. Dezember 2009, 19:43

Pekh hat geschrieben:
orossum hat geschrieben: Python stehe ich eigentlich recht offen gegenüber, obwohl es, wie sich gezeigt hat, noch einige andere Mängel aufweist. (Zum Beispiel: Performance im Allgemeinen sowie bei Arrays/Listen mit hohen Indizies, seltsame, nicht erklärbare Fehler die bei bestimmten Prozeduren auftreten [gesamte Klasse inklusive Informatik-Lehrer ratlos!], in- und dekrementelle Operatoren - warum auch immer es sie nicht gibt, usw.)
mfg
Ich kann mir ehrlich gesagt nicht vorstellen, daß man Python in der Schule an seine Leistungsgrenzen bringen kann. Gerade auch weil ich Python selbst in der Schule gelernt habe. Ich vermute hier mal dreist und ohne Hintergrundkenntnisse die Wahl einer falschen Datenstruktur bzw. eines nicht-optimalen Algorithmusses. Was die nicht-erklärbaren Fehler angeht, wäre ich doch mal sehr an Beispielen interessiert. Das Informatik-Lehrer bisweilen leider nicht das Maß der Dinge sind, wurde an anderer Stelle hier im Forum schon lang und breit diskutiert. Aber auch gestandene Programmierer sehen sich immer wieder mal in einer Situation, in der sie den Fehler einfach nicht ausmachen können und lange nach der meist recht trivialen Ursache forschen. In der Regel ist es ein Denkfehler ;)
Es gab da eine Reihe von Problemen die aufgetaucht sind, aber ich werde jetzt mal das seltsamste hernehmen (Code liegt derzeit am Schulserver herum, deshalb kann ich ihn hier nicht posten).
Hier nur eine kurzfassung:

Code: Alles auswählen

def ChangeVar(var):
    var=var+1
    print(var)

myVar=2
ChangeVar(myVar)
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:

Code: Alles auswählen

def ChangeVar(var):
    var=var+1
    print(var)

myVarOrignal=2
myVarChange=myVarOriginal
ChangeVar(myVarChange)
Resultat war wieder 3, myVarOriginal war auch wieder 3.

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.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo!
orossum hat geschrieben:Ich stufe Python durchaus als eine speziell für Anfänger geeignete Skriptsprache ein, mitsamt den daraus folgenden Vor- und Nachteilen. (Über die ihr hier sicher bestens bescheid wisst!)
Die Sprache ist nicht nur für Anfänger geeignet, sondern lässt sich auch wunderbar bei komplexeren Anwendungen einsetzen.
orossum hat geschrieben:Kaputtes Objektmodell bei Alternativen - naja.. Wenn man in Bezug nimmt, dass Python (zumindest in der Version die unsere Schule zur Verfügung stellt) einige Lücken aufweist (Public,Private nicht existent, etc.)
Auf public, private und co wurde ganz bewusst verzichtet, da diese im Prinzip überflüssig sind. Wie schon schon /me erwähnt hatte, wird in Python so etwas über Konvention geregelt. Wenn ich der Meinung bin, dass ich ein als "private" gekennzeichnetes Objekt anfassen will, dann möchte ich das auch tun können. Ich gehe davon aus, dass ich weiß was ich tue und möchte nicht, dass mir das erschwert wird.
orossum hat geschrieben:Python stehe ich eigentlich recht offen gegenüber, obwohl es, wie sich gezeigt hat, noch einige andere Mängel aufweist. (Zum Beispiel: Performance im Allgemeinen sowie bei Arrays/Listen mit hohen Indizies, seltsame, nicht erklärbare Fehler die bei bestimmten Prozeduren auftreten [gesamte Klasse inklusive Informatik-Lehrer ratlos!], in- und dekrementelle Operatoren - warum auch immer es sie nicht gibt, usw.)
Die Performance von Python ist in den meisten Fällen überhaupt kein Problem. Im Normalfall ist die Entwicklungsgeschwindigkeit entscheidender als die Ausführgeschwindigkeit.
Wenn seltsame Fehler auftreten die ihr nicht versteht, dann liegt das mit hoher Wahrscheinlichkeit nicht am Interpreter, sondern an den Personen vor dem Bildschirm ;-) Das Wissen von Informatiklehrern ist auch nicht unbegrenzt.

Das es inkrementelle Operatoren nicht gibt hat einen recht einfachen Grund: mit i++ deutest du an, dass i um 1 erhöht wird. Dies ist bei Python allerdings anders: da Zahlen nicht veränderbar sind, wird ein neues Objekt mit dem Wert i+1 erzeugt und das neue Objekt an den Namen gebunden. i++ könnte ein wenig verwirren, daher hat man sich für i += 1 als Alternative entschieden. Ob man das nun gut finden oder nicht sei jedem selbst überlassen.
Das Leben ist wie ein Tennisball.
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]
Antworten