Objektorientierte Programmierung

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.
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Hi!
Ich will das wirklich unbedingt verstehen, das ist auch der Grund warum ich mir eure Antworten schon sicher 20x durchgelesen habe. Teils wird es nun klarer. Wenn ich dann aber selbst ein "Beipiel" konstruiere, merke ich, dass - wie soll man sagen- noch das Fleisch am Knochen fehlt...

Bsp:

Code: Alles auswählen

import random

class Mathe(object):
    def __init__(self):
       self.wert1 = random.randint(1,10)
       self.wert2 = random.randint(1,10)

rechnen = Mathe()
rechnen.wert1 bzw. rechnen.wert2 gibt in dem Fall eine Zufallszahl aus
Auch Mathe().wert1 bzw. Mathe().wert2 gibt Zufallszahlen aus

Wenn ich nun aber das self. vor wert1 und wert2 entferne, kann ich die beiden werte nicht mehr aufrufen und bekomme einen AttributeError, weil das Object Mathe kein Attribut wert1 bzw. wert2 hat.

Ich hatte gedacht, ich initialisiere mit def __init__ die Werte der Klassenattribute UND bin davon ausgegangen, dass - wenn ich das self weglasse - es nur Auswirkungen auf die Instanzen des Objektes hat, die Klasse aber sehr wohl noch die Attribute wert1 und wert2 "hat".

In dem Fall aber hat dann offenbar auch die Klasse keine Attribute wert1 und wert2.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Methoden sind in Python ganz normale Funktionen, die das Objekt selbst als erstes Argument etwas magisch übergeben bekommen. Das heißt, du kannst auch folgendes machen:

Code: Alles auswählen

def my_init(obj, foo, bar):
    obj.foo=foo
    obj.bar = int(bar)

class MyClass(object): pass

MyClass.__init__ = my_init
m = MyClass('1', '1')
print m.foo, m.bar
[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
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Das Verhalten, was du beschreibst gibt es in anderen Programmiersprachen. In Python muss man das self expizit mit angeben. Das heißt

Code: Alles auswählen

def foo(self, bar):
    self #das aktuelle Objekt der Klasse, auf der die Methode ausgeführt wird
    bar #ein Parameter, der im Moment nur lokal zur Verfügung steht
    i = 0 # eine lokale Variable
    self.bar #ein Attribut des Objektes, das aber nichts mit dem bar oben zu zun hat
    self.blablub = bar #dem Attribut des Objektes wird ein Wert zugewiesen
[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

@mcdaniels: Wenn Du nur die Namen `wert1` und `wert2` hast, dann sind das ganz einfach lokale Namen in der `__init__()`-Methode, wie in jeder anderen Funktion auch. Und noch einmal: An `self` ist das Exemplar auf dem die Methode aufgerufen wurde gebunden. Nicht die Klasse, darum setzt Du damit auch keine *Klassen*attribute, sondern welche auf dem Exemplar (in schlechter und falscher Übersetzung leider sehr verbreitet auch „Instanz“ genannt).

Ich habe den Verdacht Du hast die Trennung zwischen Klasse und Exemplaren noch nicht so im Kopf wie sie sein sollte. Wenn Du schreibst „das Object Mathe [hat] kein Attribut wert1 bzw. wert2“, dann meinst Du hoffentlich das `Mathe`-Exemplar. Denn `Mathe` selbst ist ja auch der Name für ein Objekt — nämlich die Klasse.@mcdaniels: Wenn Du nur die Namen `wert1` und `wert2` hast, dann sind das ganz einfach lokale Namen in der `__init__()`-Methode, wie in jeder anderen Funktion auch. Und noch einmal: An `self` ist das Exemplar auf dem die Methode aufgerufen wurde gebunden. Nicht die Klasse, darum setzt Du damit auch keine *Klassen*attribute, sondern welche auf dem Exemplar (in schlechter und falscher Übersetzung leider sehr verbreitet auch „Instanz“ genannt).

Ich habe den Verdacht Du hast die Trennung zwischen Klasse und Exemplaren noch nicht so im Kopf wie sie sein sollte. Wenn Du schreibst „das Object Mathe [hat] kein Attribut wert1 bzw. wert2“, dann meinst Du hoffentlich das `Mathe`-Exemplar. Denn `Mathe` selbst ist ja auch der Name für ein Objekt — nämlich die Klasse.

Es gibt drei „Ebenen“ die man aus Methoden ansprechen kann: Die Klasse, die Exemplare die damit erstellt werden, und lokale Namen innerhalb der Methode. An die Klasse kommt man mit dem Namen (`Mathe`), an das Exemplar über das erste Argument (üblicherweise `self`) und lokale Namen (funktionieren genau wie bei Funktionen, wenn irgendwo innerhalb der Funktion einem Namen etwas zugewiesen wird, ist er lokal).

Es gibt drei „Ebenen“ die man aus Methoden ansprechen kann: Die Klasse, die Exemplare die damit erstellt werden, und lokale Namen innerhalb der Methode. An die Klasse kommt man mit dem Namen (`Mathe`), an das Exemplar über das erste Argument (üblicherweise `self`) und lokale Namen (funktionieren genau wie bei Funktionen, wenn irgendwo innerhalb der Funktion einem Namen etwas zugewiesen wird, ist er lokal).
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Hallo!

Klasse:

Code: Alles auswählen

import random
class Mathe(object):
    def __init__(self):
       self.wert1 = random.randint(1,10)
       self.wert2 = random.randint(1,10)
Exemplar der Klasse:
rechnen = Mathe()

Somit wäre rechnen ein Exemplar der Klasse Mathe.

Ich greife also mittels rechnen.wert1 auf den wert1 zu, der dem Exemplar der Klasse rechnen (durch self) zugewiesen ist.

Was aber, wenn ich folgendes habe:

Code: Alles auswählen

import random
class Mathe(object):
    def __init__(self):
       wert1 = random.randint(1,10)
       wert2 = random.randint(1,10)
Somit hat das Exemplar der Klasse ja keine Werte, da ich diese ja nur mittels self an das Exemplar "binde". Das wären dann in dem Fall lokale Namen?

Wie aber komme ich an wert1 und wert2 bei oben erwähntem "Programm"?


Bei einer Funktion "übergebe" ich die Variablen ja zb durch:

Code: Alles auswählen

def Mathe(wert1, wert2):
    print 'Ergebnis: ', wert1 + wert2'
und bekomme über den print Befehl dann eine Ausgabe.

oder aber ohne print mittels return:

Code: Alles auswählen

def Mathe(wert1, wert2):
    return wert1 + wert2
LG
Daniel
BlackJack

@mcdaniels: Beim zweiten Beispiel kommst Du an die Werte gar nicht heran. Das sind lokale Namen die beim Aufruf der Methode erstellt werden, nur innerhalb der Methode sichtbar sind, und nach der Abarbeitung wieder verschwinden. Da verhalten sich Methoden genau wie Funktionen.
Antworten