Aus Unterklasse Methode in Oberklasse ausführen

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.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

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.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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

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
Das Leben ist wie ein Tennisball.
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.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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).
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.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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 ?
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

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.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@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).
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

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. :D 4 Seiten !
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

feldmann_markus hat geschrieben:Ich lese ja noch. :D 4 Seiten !
Nein, das ist nur der verlinkte Post und eventuell der danach.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten