Wozu "self"?

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.
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

Freitag 21. November 2008, 05:39

Warum wurde die Sprache nicht so definiert, dass das:

Code: Alles auswählen

>>> class Complex:
...     def __init__(self, realpart, imagpart):
...         self.r = realpart
...         self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
... so aussieht:

Code: Alles auswählen

>>> class Complex:
...     def __init__(realpart, imagpart):
...         r = realpart
...         i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
Das ganze self, self, self verwirrt mich noch etwas.
Qubit
User
Beiträge: 75
Registriert: Dienstag 7. Oktober 2008, 09:07

Freitag 21. November 2008, 09:41

bremer hat geschrieben: Das ganze self, self, self verwirrt mich noch etwas.
Vorneweg:
"self" ist kein Keyword, nur Konvention, ein beliebig wählbarer Bezeichner. Ein Bezeichner wofür? Für die Referenz auf ein Objekt, also Klasse, Instanz, usw., welche im Namensraum des Objekts selbst liegt.
Dass diese Referenz (standardmäßig) explizit adressiert wird, liegt im Objektdesign von Python. Hierdurch ist es zB möglich, extern Referenzen zu übergeben, wie zB, object.__getattribute__(ref,attr). Bei Zugriffen auf die Methoden von Klassen oder Instanzen wird diese Referenz von der Python Umgebung selbst gemanaged, also bei Klass.method(cls,..) oder Klass().method(self,..) sind die Referenzen 'cls' oder 'self' vorbelegt und müssen nicht angegeben werden, da Klass oder Klass() schon (im exterenen Namensraum) referenziert sind und somit auch im Namensraum des Objekts eben als "cls" oder "self" referenziert werden können.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Freitag 21. November 2008, 09:46

Nicht alles was ich in einer Objektmethode deklariere, moechte ich automatisch als Klassenattibut haben:

Code: Alles auswählen

>>> class A:
...   def __init__(self):
...     tmp = ...
...     self.x = tmp/2 + ...
D.h. irgendeinen Mechanismus braucht man, um die lokalen Namen von den Objektattributen zu unterscheiden. Bei Java und C++ hat man z.B. ein this.x, was man allerdings bei den wenigsten anderen Sprachen hat, ist die Uebergabe des Objekts als ersten Parameter.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Freitag 21. November 2008, 10:18

Desweiteren finde ich, dass das eine gute Konvention ist.
Gegenüber Sprachen wie C++ bleiben einem ja die Deklarationen erspart.
Ich fänd es gut wenn in C++ auch immer das this Objekt verwendet werden würde.
Aber man hat ja die Freiheit diesen wegzulassen und ich finde es ärgerlich in Fremdcode nachforschen zu müssen ob es ein Member ist oder nicht.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Freitag 21. November 2008, 11:17

Wie Rebecca schon richtig sagte, bedarf es einer Trennung zwischen lokalen Namen in Methoden und Klassen- oder Instanzattribute. In deiner zweiten Beispielklasse könnten `r` und `i` auch Klassenattribute sein.

In Java gibt es, wie bereits erwähnt, das Schlüsselwort `this`. Dies ist leider optional, so dass man immer genau hinsehen muss, woran ein Objekt nun unter diesem Namen gebunden wurde (oder ob es lokal ist). Python geht hier konsequent den "explicit is better than implicit"-Weg und man ist sofort im Bilde darüber, ob man auf die Instanz (`self`), die Klasse (`cls` oder der Klassenname) oder nur einen ungebundenen Namen zugreift.

In Ruby ist es ebenfalls so, dass man keinen Präfix für Methoden benötigt. So kann sich bspw. ein Aufruf von `show` im Konstruktor auf eine Methode der selben Klasse als auch (soweit ich weiß/annehme) auf eine außerhalb der Klasse definierte Funktion beziehen. In Python wäre der Unterschied deutlich, da im ersten Fall ein `self.` davor stünde.

Ruby verwendet weiterhin `@` und `@@` als Präfixe für Instanz- respektive Klassenattribute, denn die anfangs beschriebene Unterscheidung ist notwendig.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 21. November 2008, 11:57

Y0Gi hat geschrieben:Ruby verwendet weiterhin `@` und `@@` als Präfixe für Instanz- respektive Klassenattribute, denn die anfangs beschriebene Unterscheidung ist notwendig.
Ja, das ist aber in Ruby auf syntaktischer Ebene gehandhabt und in Python ist ein Attributzugriff auf eine Instanz, nun ja, eben ein Attributzugriff und nichts weiter.

Was würde denn ohne so eine Aufteilung passieren? Deiner Argumentation nach würde jede lokale Variable jeder Funktion in der Klasse dann an die Instanz gebunden sein - ich denke nicht dass du so etwas haben wolltest, oder?
My god, it's full of CARs! | Leonidasvoice vs Modvoice
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

Freitag 21. November 2008, 13:02

Gut, das erklärt ja vieles.

Aber das erste self in der Klammern hätte man ja weglassen können.

def __init__(self, realpart, imagpart):
-->
def __init__(realpart, imagpart):

Stattdessen hätte man "self" als Keyword festschreiben können.
BlackJack

Freitag 21. November 2008, 13:12

@bremer: Das würde die Sprache komplizierter machen. Methoden sind bei ihrer Definition noch Funktionen, die erst beim Abruf von einem Objekt zu einer gebundenen Methode werden. Man kann "Methoden" als Funktionen benutzen und jedes beliebige aufrufbare Objekt als Methode an eine Klasse binden. In das Konzept passt ein implizites `self` einfach nicht rein weil nicht in allen Fällen klar ist, an was `self` denn eigentlich gebunden werden soll.
DasIch
User
Beiträge: 2465
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Freitag 21. November 2008, 14:41

bremer hat geschrieben:Aber das erste self in der Klammern hätte man ja weglassen können

Code: Alles auswählen

import this
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Freitag 21. November 2008, 14:47

Leonidas hat geschrieben:Ja, das ist aber in Ruby auf syntaktischer Ebene gehandhabt und in Python ist ein Attributzugriff auf eine Instanz, nun ja, eben ein Attributzugriff und nichts weiter.
Das ist ein wichtiger Unterschied, aber doch vollkommen okay. Wer die Anzahl an Schlüsselwörtern und Methoden für ähnliche Dinge - also quasi den TMTWWTDI-Faktor - vergleicht, wird feststellen, dass Python da offenbar mit einer simpleren, limitierteren Sprachbasis zu Werke geht - und eben so Dinge wie den Zugriff auf Klassen- und Instanzattribute mit Mitteln realisiert, die "schon da sind".
Leonidas hat geschrieben:Was würde denn ohne so eine Aufteilung passieren? Deiner Argumentation nach würde jede lokale Variable jeder Funktion in der Klasse dann an die Instanz gebunden sein - ich denke nicht dass du so etwas haben wolltest, oder?
Das bezieht sich vermutlich auf den OP?
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Freitag 21. November 2008, 16:32

Zu dem Thema vielleicht auch noch das hier, ich fand das interessant ;)
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Freitag 21. November 2008, 16:56

Y0Gi hat geschrieben:Wer die Anzahl an Schlüsselwörtern und Methoden für ähnliche Dinge - also quasi den TMTWWTDI-Faktor - vergleicht, wird feststellen, dass Python da offenbar mit einer simpleren, limitierteren Sprachbasis zu Werke geht - und eben so Dinge wie den Zugriff auf Klassen- und Instanzattribute mit Mitteln realisiert, die "schon da sind"
IMHO das einzig wirkliche Argument, das für das explizite self spricht.

Was Guide van Rossum dazu erklärt hat, hat mich überhaupt nicht überzeugt.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 21. November 2008, 17:38

helduel hat geschrieben:
Y0Gi hat geschrieben:Wer die Anzahl an Schlüsselwörtern und Methoden für ähnliche Dinge - also quasi den TMTWWTDI-Faktor - vergleicht, wird feststellen, dass Python da offenbar mit einer simpleren, limitierteren Sprachbasis zu Werke geht - und eben so Dinge wie den Zugriff auf Klassen- und Instanzattribute mit Mitteln realisiert, die "schon da sind"
IMHO das einzig wirkliche Argument, das für das explizite self spricht.
Lies dir mal murphys Erklärung durch.

@Y0Gi: Ja.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
lunar

Freitag 21. November 2008, 18:02

helduel hat geschrieben:Was Guide van Rossum dazu erklärt hat, hat mich überhaupt nicht überzeugt.
Darf man fragen, warum, bzw. wie du die Punkte – insbesondere die über Dekoratoren und ihr Zusammenspiel mit self – entkräften würdest?
BlackJack

Freitag 21. November 2008, 18:08

@helduel: Die Probleme. die entstehen wenn man Funktionen nicht in Klassen definiert oder innerhalb von anderen Funktionen/Methoden oder bei Dekoratoren, sind keine Argumente?
Antworten