PyBeginner: Fragen zu super(self)__init()

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.
Antworten
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Hallo im Forum,

Habe jetzt schon einiges in Python/PyQt programmiert, aber eines immer noch nicht ganz begriffen, habe es aber immer mit "probieren" hingekriegt. Das nervt ! Jetzt möchte ich es gerne doch mal genau kapieren !

Beispiel:

Code: Alles auswählen

class TestApp(PyQt4.QtGui.QDialog):
    def __init__(self, parent=None): 
        super(TestApp, self).__init__(parent)    
Was da im Prinzip gemacht wird, ist mir eigentlich klar, nur Folgendes noch nicht so ganz:

1. Problem: wann brauche ich in Zeile 2 das "parent=None" und wann nicht ?
2. Problem: warum steht da in Zeile 3 statt "super(TestApp,..." machmal aber auch so etwas wie "super(PyQt4.QtGui.QDialog,...) ?

Grüße
m-o
BlackJack

@mephisto-online: Ad 1. Das brauchst Du immer dann wenn Du dem Benutzer die Wahl lassen willst ob er die Klasse mit einem Elternobjekt erstellen möchte oder nicht.

Ad 2. Bei `super()` sollte die Klasse selbst angegeben werden. Bei ``super(PyQt4.QtGui.QDialog)`` wird oberhalb von `QDialog` in der Klassenhierarchie nach einer Methode gesucht, das heisst man kann damit keine Methoden von `QDialog` selbst aufrufen, wenn man das also in einer Unterklasse von `QDialog` macht, dann will man entweder explizit eine Methode von `QWidget` oder `QObject` aufrufen die von `QDialog` überschrieben wurde, was mindestens mal ein fragwürdiges vorgehen ist, oder man hat schlicht einen Fehler gemacht.
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:...Das brauchst Du immer dann wenn Du dem Benutzer die Wahl lassen willst ob er die Klasse mit einem Elternobjekt erstellen möchte oder nicht.
Also wenn die Klasse keine eigene ___init() haben muss ? Normal sieht das ja meist in etwa so aus:

Code: Alles auswählen

class EditData(QtGui.QDialog):

    def __init__(self, data):
        super(EditData, self).__init__()
        QtGui.QDialog.__init__(self)
BlackJack hat geschrieben:Ad 2. Bei `super()` sollte die Klasse selbst angegeben werden. ....
Kam mir anders auch irgendwie komisch vor !
BlackJack

@mephisto-online: Bei `EditData` rufst Du die `__init__()` der Basisklasse ja zweimal auf. Und ich würde hier auch die Möglichkeit geben ein Elternobjekt zu übergeben. Was ich nach Möglichkeit auch immer machen würde.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

mephisto-online hat geschrieben:Normal sieht das ja meist in etwa so aus:

Code: Alles auswählen

class EditData(QtGui.QDialog):

    def __init__(self, data):
        super(EditData, self).__init__()
        QtGui.QDialog.__init__(self)
Das halte ich jetzt nicht im Geringsten für normal. Hier wird der Aufruf der Elternmethode sowohl new-style wie auch old-style durchgeführt.

Code: Alles auswählen

>>> class Foo(object):
	def __init__(self):
		print('Foo.__init__ called')

		
>>> class Bar(Foo):
	def __init__(self):
		super(Bar, self).__init__()
		Foo.__init__(self)

		
>>> thing = Bar()
Foo.__init__ called
Foo.__init__ called
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:Bei `EditData` rufst Du die `__init__()` der Basisklasse ja zweimal auf.

Wenn ich genau hinsehe: "Stimmt auffallend". Doppelt gemoppelt hält hier nicht besser, sondern ist schlicht gesagt einfach nur dämlich. :oops:
BlackJack hat geschrieben:Und ich würde hier auch die Möglichkeit geben ein Elternobjekt zu übergeben. Was ich nach Möglichkeit auch immer machen würde.
Und wie würde das aussehen ? Hört sich so an, als wenn "Elternobjekt übergeben" was anderes ist, als vererben (hier von QtGui.QDialog).

@/me
/me hat geschrieben: Das halte ich jetzt nicht im Geringsten für normal. Hier wird der Aufruf der Elternmethode sowohl new-style wie auch old-style durchgeführt.
Old-Style-New-Style ? Ja, auch schon gelesen, aber wohl noch nicht verinnerlicht oder durcheinander gebracht :oops: Dein Beispiel zeigt das gleiche, was BlackJack schon gesagt hat.

Es ist also so, dass durch eine Vererbung einer Klasse nicht automatisch deren ___init() aufgerufen wird ? Das muss ich also generell selbst erledigen ? Grundsätzlich ?
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:Bei `EditData` rufst Du die `__init__()` der Basisklasse ja zweimal auf.

Wenn ich genau hinsehe: "Stimmt auffallend". Doppelt gemoppelt hält hier nicht besser, sondern ist schlicht gesagt einfach nur dämlich. :oops:
BlackJack hat geschrieben:Und ich würde hier auch die Möglichkeit geben ein Elternobjekt zu übergeben. Was ich nach Möglichkeit auch immer machen würde.
Und wie würde das aussehen ? Hört sich so an, als wenn "Elternobjekt übergeben" was anderes ist, als vererben (hier von QtGui.QDialog).

@/me
/me hat geschrieben: Das halte ich jetzt nicht im Geringsten für normal. Hier wird der Aufruf der Elternmethode sowohl new-style wie auch old-style durchgeführt.
Old-Style-New-Style ? Ja, auch schon gelesen, aber wohl noch nicht verinnerlicht oder durcheinander gebracht :oops: Dein Beispiel zeigt das gleiche, was BlackJack schon gesagt hat.

Es ist also so, dass durch eine Vererbung einer Klasse nicht automatisch deren ___init() aufgerufen wird ? Das muss ich also generell selbst erledigen ? Grundsätzlich ?
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:Bei `EditData` rufst Du die `__init__()` der Basisklasse ja zweimal auf.

Wenn ich genau hinsehe: "Stimmt auffallend". Doppelt gemoppelt hält hier nicht besser, sondern ist schlicht gesagt einfach nur dämlich. :oops:
BlackJack hat geschrieben:Und ich würde hier auch die Möglichkeit geben ein Elternobjekt zu übergeben. Was ich nach Möglichkeit auch immer machen würde.
Und wie würde das aussehen ? Hört sich so an, als wenn "Elternobjekt übergeben" was anderes ist, als vererben (hier von QtGui.QDialog).

@/me
/me hat geschrieben: Das halte ich jetzt nicht im Geringsten für normal. Hier wird der Aufruf der Elternmethode sowohl new-style wie auch old-style durchgeführt.
Old-Style-New-Style ? Ja, auch schon gelesen, aber wohl noch nicht verinnerlicht oder durcheinander gebracht :oops: Dein Beispiel zeigt das gleiche, was BlackJack schon gesagt hat.

Es ist also so, dass durch eine Vererbung einer Klasse nicht automatisch deren ___init() aufgerufen wird ? Das muss ich also generell selbst erledigen ? Grundsätzlich ?
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:Bei `EditData` rufst Du die `__init__()` der Basisklasse ja zweimal auf.

Wenn ich genau hinsehe: "Stimmt auffallend". Doppelt gemoppelt hält hier nicht besser, sondern ist schlicht gesagt einfach nur dämlich. :oops:
BlackJack hat geschrieben:Und ich würde hier auch die Möglichkeit geben ein Elternobjekt zu übergeben. Was ich nach Möglichkeit auch immer machen würde.
Und wie würde das aussehen ? Hört sich so an, als wenn "Elternobjekt übergeben" was anderes ist, als vererben (hier von QtGui.QDialog).

@/me
/me hat geschrieben: Das halte ich jetzt nicht im Geringsten für normal. Hier wird der Aufruf der Elternmethode sowohl new-style wie auch old-style durchgeführt.
Old-Style-New-Style ? Ja, auch schon gelesen, aber wohl noch nicht verinnerlicht oder durcheinander gebracht :oops: Dein Beispiel zeigt das gleiche, was BlackJack schon gesagt hat.

Es ist also so, dass durch eine Vererbung einer Klasse nicht automatisch deren ___init() aufgerufen wird ? Das muss ich also generell selbst erledigen ? Grundsätzlich ?
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:Bei `EditData` rufst Du die `__init__()` der Basisklasse ja zweimal auf.

Wenn ich genau hinsehe: "Stimmt auffallend". Doppelt gemoppelt hält hier nicht besser, sondern ist schlicht gesagt einfach nur dämlich. :oops:
BlackJack hat geschrieben:Und ich würde hier auch die Möglichkeit geben ein Elternobjekt zu übergeben. Was ich nach Möglichkeit auch immer machen würde.
Und wie würde das aussehen ? Hört sich so an, als wenn "Elternobjekt übergeben" was anderes ist, als vererben (hier von QtGui.QDialog).

@/me
/me hat geschrieben: Das halte ich jetzt nicht im Geringsten für normal. Hier wird der Aufruf der Elternmethode sowohl new-style wie auch old-style durchgeführt.
Old-Style-New-Style ? Ja, auch schon gelesen, aber wohl noch nicht verinnerlicht oder durcheinander gebracht :oops: Dein Beispiel zeigt das gleiche, was BlackJack schon gesagt hat.

Es ist also so, dass durch eine Vererbung einer Klasse nicht automatisch deren ___init() aufgerufen wird ? Das muss ich also generell selbst erledigen ? Grundsätzlich ?
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:Bei `EditData` rufst Du die `__init__()` der Basisklasse ja zweimal auf.

Wenn ich genau hinsehe: "Stimmt auffallend". Doppelt gemoppelt hält hier nicht besser, sondern ist schlicht gesagt einfach nur dämlich. :oops:
BlackJack hat geschrieben:Und ich würde hier auch die Möglichkeit geben ein Elternobjekt zu übergeben. Was ich nach Möglichkeit auch immer machen würde.
Und wie würde das aussehen ? Hört sich so an, als wenn "Elternobjekt übergeben" was anderes ist, als vererben (hier von QtGui.QDialog).

@/me
/me hat geschrieben: Das halte ich jetzt nicht im Geringsten für normal. Hier wird der Aufruf der Elternmethode sowohl new-style wie auch old-style durchgeführt.
Old-Style-New-Style ? Ja, auch schon gelesen, aber wohl noch nicht verinnerlicht oder durcheinander gebracht :oops: Dein Beispiel zeigt das gleiche, was BlackJack schon gesagt hat.

Es ist also so, dass durch eine Vererbung einer Klasse nicht automatisch deren ___init() aufgerufen wird ? Das muss ich also generell selbst erledigen ? Grundsätzlich ?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

mephisto-online hat geschrieben:Es ist also so, dass durch eine Vererbung einer Klasse nicht automatisch deren ___init() aufgerufen wird ? Das muss ich also generell selbst erledigen ? Grundsätzlich ?
Wenn du selber keine Methode (wie z.B. __init__) deklarierst, dann wird sie in der Elternklasse gesucht. Definierst du sie, dann ist es deine Verantwortung bei Bedarf die entsprechende Methode der Elternklasse aufzurufen. Ein Aufruf erfolgt in diesem Fall nicht automatisch, da das Flexibilität wegnehmen würde.

Code: Alles auswählen

>>> class Foo(object):
	def __init__(self):
		print('Foo.__init__ called')

>>> class Bar(Foo):
	pass

>>> thing = Bar()
Foo.__init__ called
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Danke, genau das wollte ich wissen !

Dann habe ich das jetzt endgültig kapiert ... :D

Grüße
m-o
Antworten