Seite 1 von 2
Aus Unterklasse Methode in Oberklasse ausführen
Verfasst: Freitag 19. Juni 2009, 22:17
von feldmaus
Hi alle,
ist es möglich in Python aus einer Unterklasse eine Methode in der Oberklasse aufzurufen ?
Ich habe Slider und Eingabe Elemente in eine Klasse gekappselt, der Übersicht halber. Ansonsten würde ich die Elemte in die Oberklasse nehmen.
Hat Jemand da ein gutes parade Beispiel für mich ?
Grüße Markus
Verfasst: Freitag 19. Juni 2009, 22:42
von str1442
Code: Alles auswählen
In [1]: class A(object):
...: def method(self):
...: print "Superklasse"
...:
...:
In [2]: class B(A):
...: def method(self):
...: super(B, self).method()
...: print "Subklasse, welche Superklasse erweitert"
...:
...:
In [3]: B().method()
Superklasse
Subklasse, welche Superklasse erweitert
So sollte man es auch machen - eine Subklasse sollte immer (es sei denn, man hat einen guten Grund dazu und so weiter) die Superklasse erweitern und deren Implementation aufrufen.
Ich habe Slider und Eingabe Elemente in eine Klasse gekappselt, der Übersicht halber. Ansonsten würde ich die Elemte in die Oberklasse nehmen.
Könntest du das genauer beschreiben? Welche Elemente der Oberklasse? Wenn du nämlich nicht das willst, was ich gerade gezeigt habe, und bei Elemente eigentlich Methoden stehen sollte, hört sich das böse an.
Verfasst: Freitag 19. Juni 2009, 23:46
von feldmaus
Ok ich versuche mal ein Beispiel so simpel wie möglich.
Code: Alles auswählen
class A:
sliderGroup1 = B()
sliderGroup2 = B()
def changeGrafik():
def changeSliderGroup():
def zeichneGrafik1(t,y):
plot(t,y)
def zeichneGrafik2(t,y)
plot(t,y)
class B:
slider = wx.Slider()
sliderText = wx.TextCtrl()
self.slider.Bind(wx.EVT_SLIDER, self.sliderHandler)
self.sliderText.Bind(wx.EVT_TEXT_ENTER, self.sliderTextHandler)
def sliderHandler:
zeichneGrafik(t,y)
def sliderTextHandler
zeichneGrafik(t,y)
An sich hast Du mich schon ganz gut verstanden, glaube ich. Ich nutze zwei Plot's,
die unterschiedliche Slider Einstellungen nutzen. Ich will aber nur ein Slider
haben. D.h. ich muss die Einstellunngen des Slider mit dem ändern der Grafik ebend-
fallls ändern können.
Der andere Punkt ist halt, dass bei ändern des Slider-Reglers die Grafik neu gezeichnet
werden soll.
Ich hoffe das war verständlich. Ich nutze ein Beispiel, welches ich aber noch nicht ganz
verstanden habe und das ist für die Objekt orientierte Programmierung sehr wichtig.
In diesem Beispiel wird der Begriff "parent" verwendet, ist das das gleiche wie den
Namen der Klasse angeben ?
Ist super(B, self) eine Methode von B() ?
Grüße Markus
Verfasst: Samstag 20. Juni 2009, 00:30
von EyDu
Du solltest dich vielleich zunächst mal ohne eine GUI in Objektorientierung einarbeiten. Die Klassenvariablen zeugen noch nicht von wirklichem Verständnis.
feldmann_markus hat geschrieben:Ist super(B, self) eine Methode von B() ?
http://docs.python.org/library/functions.html#super
Verfasst: Samstag 20. Juni 2009, 05:32
von BlackJack
Wobei ich um `super()` einen grossen Bogen mache, seitdem ich dass hier gelesen hatte:
Python's Super is nifty, but you can't use it.
Verfasst: Samstag 20. Juni 2009, 11:33
von feldmaus
EyDu hat geschrieben:Du solltest dich vielleich zunächst mal ohne eine GUI in Objektorientierung einarbeiten. Die Klassenvariablen zeugen noch nicht von wirklichem Verständnis.
In den Beispielen und Dokus zu Klassen finde ich nur einfache Vererbungsgeschichten,
aber nichts mit Interaktionen zwischen Klassen.
Wahrscheinlich wird das anders gemacht. Eine andere Idee wäre die Klasse B an die
Klasse A zu vererben, dann könnte er vielleicht die Methoden der Klasse A aufrufen ?
Grüße Markus
Verfasst: Samstag 20. Juni 2009, 12:15
von cofi
Du rufst einfach die Methoden der Basisklasse auf und übergibst dann ``self``.
Wenn das keine Mehrfachvererbung ist, dürfte es auch keine Probleme mit ``super`` geben (und ``__init__`` die gleichen Parameter nimmt).
Verfasst: Samstag 20. Juni 2009, 12:19
von BlackJack
@feldmann_markus: Vererbung verwendet man bei "ist-ein(e)"-Beziehungen, also wenn B semantisch auch ein A ist, dann kann man B von A erben lassen. Also zum Beispiel kann man `Auto` von `Fahrzeug` erben lassen, aber man sollte nicht `Tankwart` von `Fahrzeug` erben lassen, weil der auf `Fahrzeug.betanken()` zugreifen können soll.
Verfasst: Samstag 20. Juni 2009, 12:26
von feldmaus
BlackJack hat geschrieben:@feldmann_markus: Vererbung verwendet man bei "ist-ein(e)"-Beziehungen, also wenn B semantisch auch ein A ist, dann kann man B von A erben lassen. Also zum Beispiel kann man `Auto` von `Fahrzeug` erben lassen, aber man sollte nicht `Tankwart` von `Fahrzeug` erben lassen, weil der auf `Fahrzeug.betanken()` zugreifen können soll.
Genauso habe ich Klassen auch verstanden, und in diesem Sinne ist Vererbung für meinen Fall nicht sinnvoll. Abgesehen davon würde es bei sehr vielen Klassen die komplizierte
Zusammenhänge zueinander haben eh nicht funktionieren, also muss es dafür eine andere
Lösung geben.
Verfasst: Samstag 20. Juni 2009, 12:30
von feldmaus
cofi hat geschrieben:Du rufst einfach die Methoden der Basisklasse auf und übergibst dann ``self``.
Wenn das keine Mehrfachvererbung ist, dürfte es auch keine Probleme mit ``super`` geben (und ``__init__`` die gleichen Parameter nimmt).
Ich glaube mit super könnte das bei mir ein Problem werden, da ich im __init__ meiner
Klasse A alles rund um Grafik(Fenster, Buttons ...) instanziere und auch die SliderGroup.
Dies würde dann mit super zu einer endlos Schleife führen ?
Verfasst: Samstag 20. Juni 2009, 14:10
von jerch
feldmann_markus hat geschrieben:...
Ich will aber nur ein Slider
haben. D.h. ich muss die Einstellunngen des Slider mit dem ändern der Grafik ebend-
fallls ändern können.
Der andere Punkt ist halt, dass bei ändern des Slider-Reglers die Grafik neu gezeichnet
werden soll.
...
Diese Anforderungen sind doch ein klassischer Fall von signaling. D.h. Deine Graphik- und Sliderobjekte leben nebeneinander und müssen auch garnichts vom inneren Aufbau des anderen wissen. Nur Änderungen, die den jeweils anderen auch was angehen, werden mit Signalen announciert, und das Zielobjekt entscheidet, was zu tun ist.
Ich denke, daß Dein Weg über seltsame Klassenvariablenkonstrukte bzw. super() die falsche Herangehensweise ist.
Verfasst: Samstag 20. Juni 2009, 14:39
von feldmaus
jerch hat geschrieben:feldmann_markus hat geschrieben:...
Ich will aber nur ein Slider
haben. D.h. ich muss die Einstellunngen des Slider mit dem ändern der Grafik ebend-
fallls ändern können.
Der andere Punkt ist halt, dass bei ändern des Slider-Reglers die Grafik neu gezeichnet
werden soll.
...
Diese Anforderungen sind doch ein klassischer Fall von signaling. D.h. Deine Graphik- und Sliderobjekte leben nebeneinander und müssen auch garnichts vom inneren Aufbau des anderen wissen. Nur Änderungen, die den jeweils anderen auch was angehen, werden mit Signalen announciert, und das Zielobjekt entscheidet, was zu tun ist.
Ich denke, daß Dein Weg über seltsame Klassenvariablenkonstrukte bzw. super() die falsche Herangehensweise ist.
Ich denke auch das Vererbung und die super Funktion für mich nicht das richtige ist.
Das das ganze mit Signaling zu tun hat ist schon mal klar aber trotzdem muss das
ganze doch zu kapseln sein, auch wenn die grafischen Elemente durch bind()
miteinander interagieren.
Grüße Markus
Verfasst: Samstag 20. Juni 2009, 15:20
von jerch
@feldmann_markus:
Was meinst Du mit Kaspelung? Ein "Überobjekt"? Kann sein, daß ich Dich falsch verstanden habe, zumindest könnte man sowas derart bauen (Freitext):
Gegengebene Klassen
- Klasse Slider
- Klasse Graphic
- Klasse Uber
zu Uber:
- Konstruktor Uber instantiiert Slider --> einmal Objekt slider; ein uber.actual_graphic zeigt auf das aktive graphic-Objekt (None zu Anfang)
- uber.add_graphic() erstellt Graphic-Instanz, wird in Liste von graphic-Objekten eingefügt
- uber.focus_change() zeigt an, das das aktive graphic-Objekt gewechselt wurde; uber.actual_graphic und slider aktualisieren
- Signale werden alle von uber von slider-->uber.actual_graphic und von uber.actual_graphic-->slider geroutet
Entspricht das in etwa Deinen Vorstellungen? Falls nicht, solltest Du vllt. die Anforderungen nochmal in Freitext genauer erklären.
Edit:
Wie man das dann konkret umsetzt, hängt von den Gegebenheiten des eingesetzten Gui-Toolkits ab. Mit wx kenne ich mich nicht so gut aus, in PyQt gibts ein paar Klassen, die einem hier teilweise die Arbeit abnehmen können (z.B. StackedWigdet für die Focussache).
Verfasst: Samstag 20. Juni 2009, 16:27
von feldmaus
Ich glaube jetzt habe ich den Begriff in C++ gefunden, hatte mich damals schon tierisch
genervt. Den genauen Wortlaut weiß ich nicht mehr ich glaube es hieß,
Übergabe von Zeigern auf eine Adresse eines Elementes eines Objektes
Damit können Objekte interagieren. Ich versuche gerade das in Python zu realisieren und
melde mich nachher nochmal.
Verfasst: Samstag 20. Juni 2009, 16:59
von feldmaus
Ich versuche mal zu erklären was ich damit meine und was ich will,
Code: Alles auswählen
class A:
sliderGroup = B()
sliderGroup.attach(self)
def zeichneGrafik(t,y):
plot(t,y)
class B:
self.adresseAufrufer = None
slider = wx.Slider()
self.slider.Bind(wx.EVT_SLIDER, self.sliderHandler)
def sliderHandler:
self.adresseAufrufer.zeichneGrafik(t,y)
def attach(self,aufrufer)
self.adresseAufrufer = aufrufer
Das ganze funktioniert bei mir nicht wirklich aber im Beispiel
http://matplotlib.sourceforge.net/examp ... ght=slider kann man sehen wie das funktioniert.
Ich habe das Beispiel mal hochgeladen nach pastebin,
http://pastebin.com/m26ae0d02
Speziell Zeile 133 und 134 zeigt die Übergabe der Adresse des Elementes, die dann
später benutzt wird um eine Methode in der Klasse des Aufrufers zu starten, Zeile 49
bis 51.
Hoffe das war jetzt verständlich. Ich muss nur wissen wie ich das bei mir rein gebaut
bekomme, es funktioniert nämlich bei mir nicht.
Grüße Markus
Verfasst: Samstag 20. Juni 2009, 17:52
von Leonidas
Außerhalb von Methoden, inndehab von Klassendefinitionen ist ``self`` natürlich nicht gültig, weil die Methoden das erst als Parameter mitbekommen.
Und dein Beispiel sähe in Python so aus:
Code: Alles auswählen
class A(object):
def __init__(self):
self.sliderGroup = B(self)
def zeichneGrafik(self, t,y):
plot(t,y)
class B(object):
def __init__(self, aufrufer):
self.aufrufer = aufrufer
self.slider = wx.Slider()
self.slider.Bind(wx.EVT_SLIDER, self.sliderHandler)
def sliderHandler(self):
self.aufrufer.zeichneGrafik(t,y)
Achja, und lies dir bitte
das noch durch
Verfasst: Samstag 20. Juni 2009, 18:22
von feldmaus
So dann kommen wir mal zu den Feinheiten.
Benötige ich Objekt, meine Klasse A erbt nämlich schon von wx.Frame ?
Und die __init__ Methode von meiner Klasse B enthält noch ein parent,
wo ich bis jetzt noch nichts brauchbares zu gefunden habe. Benötige
ich parent ? Wo steht was zu parent ?
Die aufgerufene Methode in Zeile 15 von deinem Beispiel(Leonidas) greift auf Daten zu,
die in Klasse A definiert wurden. Geht das ?
Grüße Markus
Verfasst: Samstag 20. Juni 2009, 18:25
von Leonidas
feldmann_markus hat geschrieben:So dann kommen wir mal zu den Feinheiten.

Du hast den Link unten in meinem Post entweder nicht gelesen oder ignoriert. Hole das bitte nach.
feldmann_markus hat geschrieben:Benötige ich Objekt, meine Klasse A erbt nämlich schon von wx.Frame ?
Sofern wx.Frame oder eine seiner Elternklassen schon von ``object`` erben, nicht.
feldmann_markus hat geschrieben:Und die __init__ Methode von meiner Klasse B enthält noch ein parent,
wo ich bis jetzt noch nichts brauchbares zu gefunden habe. Benötige
ich parent ? Wo steht was zu parent ?
In der wx-Dokumentation..
feldmann_markus hat geschrieben:Die aufgerufene Methode in Zeile 15 von deinem Beispiel(Leonidas) graift auf Daten zu,
die in Klasse A definiert wurden. Geht das ?
Die Daten wurden nirgendwo definiert, weder in ``A`` noch in ``B``. Natürlich kann eine Methode nur auf die Daten zugreifen, die sie über Namen erreichen kann.
Verfasst: Samstag 20. Juni 2009, 18:39
von feldmaus
Leonidas hat geschrieben:feldmann_markus hat geschrieben:So dann kommen wir mal zu den Feinheiten.

Du hast den Link unten in meinem Post entweder nicht gelesen oder ignoriert. Hole das bitte nach.
Ich lese ja noch.

4 Seiten !
Verfasst: Samstag 20. Juni 2009, 18:51
von Leonidas
feldmann_markus hat geschrieben:Ich lese ja noch.

4 Seiten !
Nein, das ist nur der verlinkte Post und eventuell der danach.