Seite 1 von 2
Frage zur OOP in Python
Verfasst: Mittwoch 9. Dezember 2009, 19:52
von orossum
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
Verfasst: Mittwoch 9. Dezember 2009, 20:08
von Pekh
Wenn du
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.
Verfasst: Mittwoch 9. Dezember 2009, 20:11
von jbs
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
Verfasst: Mittwoch 9. Dezember 2009, 20:43
von 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`.
Re: Frage zur OOP in Python
Verfasst: Mittwoch 9. Dezember 2009, 20:56
von cofi
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".
Verfasst: Mittwoch 9. Dezember 2009, 21:31
von 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?
Re: Frage zur OOP in Python
Verfasst: Mittwoch 9. Dezember 2009, 21:34
von numerix
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!
Verfasst: Mittwoch 9. Dezember 2009, 22:10
von cofi
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

Verfasst: Mittwoch 9. Dezember 2009, 22:29
von 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

Verfasst: Mittwoch 9. Dezember 2009, 22:30
von orossum
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
Verfasst: Mittwoch 9. Dezember 2009, 22:39
von /me
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.
Verfasst: Mittwoch 9. Dezember 2009, 22:45
von numerix
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?
Verfasst: Mittwoch 9. Dezember 2009, 22:45
von Pekh
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

Verfasst: Mittwoch 9. Dezember 2009, 22:58
von orossum
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.
Verfasst: Mittwoch 9. Dezember 2009, 23:06
von EyDu
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.
Verfasst: Mittwoch 9. Dezember 2009, 23:14
von EyDu
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]
Verfasst: Mittwoch 9. Dezember 2009, 23:19
von Darii
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.
Verfasst: Mittwoch 9. Dezember 2009, 23:35
von jbs
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?
Verfasst: Mittwoch 9. Dezember 2009, 23:55
von numerix
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.
Verfasst: Donnerstag 10. Dezember 2009, 00:10
von jbs
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.