initialisieren mit super() in Qt

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
malikno
User
Beiträge: 26
Registriert: Sonntag 10. April 2011, 21:47

hallo

das hier funktioniert

Code: Alles auswählen

 
class dryair(object):
   def __init__(self):
        
       self.cpi = 1.0
        
class test(dryair):
    def __init__(self):
        super(test,self).__init__()
        self.update()
        
    def update(self):
        print self.cpi

a = test()
print a.update()
das gleiche möchte ich nun auch machen, wobei ich einen wert von einer basisklasse übernehme und den dann in einem label-feld, welches mit einem qt designer erzeugt worden ist anzeigen lassen. siehe folgenden code, welcher nicht funktioniert. hierbei soll von der dryair.py von der klasse dryair self.cpi = 1.0 in die neue klasse main_OrcDlg übernommen werden. kann mir jemand helfen ?

Code: Alles auswählen

class main_OrcDlg(QDialog,ui_OrcDlg.Ui_OrcDlg, dryair.dryair):
    
    def __init__(self, parent=None):
        super(main_OrcDlg, self).__init__(parent)
         
        self.setupUi(self) #reinladen von gui welche mit qt designer erzeugt worden ist, und was eine ein label mit namen    #cpi_label besitzt

        self.connect(self.VolButton, SIGNAL("clicked()"),self.open_fluegasDlg_vol)
        self.connect(self.MassButton, SIGNAL("clicked()"),self.open_fluegasDlg_mass)        
        self.updateData()
        
    def updateData(self):
        self.cpi_label.setText("cp_i = %s<br>" % (self.cpi))
#...
wär super wenn wer eine lösung hätte.

lg martin
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

siehe folgenden code, welcher nicht funktioniert.
Wie äußerst sich das genau?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
malikno
User
Beiträge: 26
Registriert: Sonntag 10. April 2011, 21:47

also wenn ich cpi nicht direkt im main_OrcDlg mit z.Bsp. self.cpi=1.0 definiere, dann kommt folgender fehler.

Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
File "C:\Python26\lib\site-packages\spyderlib\widgets\externalshell\startup.py", line 122, in runfile
execfile(filename, glbs)
File "C:\Users\e0526979\Desktop\Diplomarbeit\ORC optimisation\ORC\src\Orc_main.py", line 105, in <module>
main = main_OrcDlg()
File "C:\Users\e0526979\Desktop\Diplomarbeit\ORC optimisation\ORC\src\Orc_main.py", line 47, in __init__
self.updateData()
File "C:\Users\e0526979\Desktop\Diplomarbeit\ORC optimisation\ORC\src\Orc_main.py", line 50, in updateData
self.cpi_label.setText("r_N2 = %s<br>" % (self.cpi))
AttributeError: 'main_OrcDlg' object has no attribute 'cpi'
lunar

@malikno: Die Quintessenz davon ist, dass "super()" die falsche Basisklasse, nämlich "QDialog", auswählt, und darauf ".__init__()" aufruft. Anders würde es bereits beim Aufruf von ".__init__()" einen Fehler geben, da "dryair.__init__()" gar keine Argumente entgegen nimmt und somit mit "parent" gar nichts anfangen kann.

Wenn Du unbedingt Hierarchien mit mehreren Basisklassen aufbauen möchtest, dann vermeide "super()" und rufe die Konstruktoren der Basisklasse manuell in der richtigen Reihenfolge auf. Am besten aber vermeidest Du Vererbungshierarchen mit mehreren Basisklassen, die nicht nur reine Mixins sind, sondern wechselseitig Methoden überschreiben (in diesem Fall ".__init__()"). Da blickt nämlich ab einer gewissen Komplexität niemand mehr durch. Du selbst verstehst ja bereits jetzt nicht mehr, was genau passiert und welche Methoden welcher Klasse in welcher Reihenfolge mit welchen Argumenten aufgerufen werden (was Du aber alles wissen müsstest, um den Quelltext zu verstehen).
malikno
User
Beiträge: 26
Registriert: Sonntag 10. April 2011, 21:47

vielen dank erstmal für eure antworten. damit ich es richtig verstehe, frag ich nochmals. super wird also nur verwendet wenn man zum beispiel nur "eine" basisklasse hat. bei mehreren basisklassen muss man jeweils die einzelnen basisklassen in der betrachteten klasse "jeweils eigens" initialisieren. ist das jetzt so richtig ausgedrückt?

ich hätte eigentlich nur mehrere basisklassen verwendet, damit ich in denen werte initialisiere und anschließend an die klasse mainOrcDlg übergebe. Bsp. self.cpi = 1.0. In der klasse dryair, hätte ich zum beispiell nun mehrere werte initialisiert und diese dann einfach übergeben, also ich hätte das system mit mehreren basisklassen nur verwendet um werte zu übergeben um die klasse mainOrcDlg schlanker zu machen. ich hätte zum beipiel keine methoden in der dryair untergebracht um diese dann später in der mainOrcDlg aufzurufen.

fazit ich hätte mehrere basisklassen eigntlich nur deshalb definiert um werte an die mainOrcDlg klasse zu übergeben, jedoch keine methoden.

ist das sinnvoll, oder sollte man das vermeiden und alles in main initialisieren?

lg
lunar

Darf ich Dich bitte, auf Groß- und Kleinschreibung und Interpunktion zu achten? Zumindest für meinen Teil sind Deine Beiträge in ihrer gegenwärtigen Form eher unangenehm zu lesen.

Wenn Du "super()" verwendest, müssen alle Klassen in der Vererbungshierarchie ebenfalls "super()" nutzen, damit die überschriebenen Methoden in der richtigen Reihenfolge (= MRO) aufgerufen werden. Deswegen weist der von BlackJack erwähnte Artikel ja auch explizit darauf hin, dass die Verwendung von "super()" in den Methoden einer Klasse Bestandteil der öffentlichen API ist und entsprechend dokumentiert werden muss. Qt-Klassen nutzen meines Wissens kein "super()", ebenso wenig wie viele andere Drittbibliotheken, weswegen "super()" in Python 2 meist keine gute Idee ist.

Den Rest Deines Beitrags verstehe ich nicht zur Gänze. Du verwendest Basisklassen nur und ausschließlich, um Exemplarvariablen zu initialisieren?! Wieso initialisierst Du die Exemplarvariablen nicht einfach in "main_OrcDlg.__init__()"? Willst Du ernsthaft behaupten, es wäre übersichtlicher, wenn Du die Initialisierung über möglichst viele Basisklassen streust?!

Ich fürchte fast, Du hast Sinn und Zweck von Vererbung noch nicht so ganz verstanden ...

Bezüglich der Namensgebung der Klassen verweise ich Dich auf PEP 8.
malikno
User
Beiträge: 26
Registriert: Sonntag 10. April 2011, 21:47

danke. das mit dem super ist mir jetzt klar. das mit der vererbung ist mir schon bewusst. da in meiner main klasse mehrere methoden folgen und und ich sehr viele eingabewerte habe, hatte ich die idee mit den auslagern von variablen auf eine weitere basisklasse. ich selbst bin noch nicht 100% vertraut mit OOP, da ich zumeist nur numerisch programmiert habe bisher. deshalb auch diese fragen.

danke für eure antworten.

lg
Antworten