Konstruktor bekommt 2 Argumente, der Interpreter findet drei

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.
Flo668
User
Beiträge: 39
Registriert: Mittwoch 23. Juli 2008, 10:41

Donnerstag 21. August 2008, 16:35

Moin!

Erstmal der Code:

Code: Alles auswählen

class ClProject():
    
    def __init__(self, pName, pPath):
        self.pName = pName
        self.pPath = pPath

# usf.

class TxMainDialog():
    
    __projExists = False
    __projName = None
    __topLeveLFolder = None 
    __NewProject = None

    def __init__(self):

            self.__topLeveLFolder = self.dialogResult['textFieldShotName']
            self.__projName = self.dialogResult['textFieldProjektName']

            self.__NewProject = ClProject(self.__projName, self.__topLeveLFolder) 
In der letzten Zeile meint der Interpreter einen Type Error zu finden:

"self.__NewProject = ClProject(self.__projName, self.__topLeveLFolder)

__init__() takes exactly 2 arguments (3given)

Also ich seh da zwei Argumente, die ich dem Kontruktor übergebe, keine drei, wo findet der Interpreter die?

Danke fuer Eure Kommentare und Hilfe.
DasIch
User
Beiträge: 2465
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Donnerstag 21. August 2008, 16:38

`self` dürfte das dritte Argument sein dass übergeben wird.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Donnerstag 21. August 2008, 16:47

Hier muss irgendwo anders etwas faul sein.

Die __init__() Methode der Klasse ClProject erwartet ja in der Tat genau drei Parameter - inkl. dem self. Da beim Aufruf eine Umwandlung erfolgt, werden bei der Instanzbildung von ClProject tatsächlich drei Parameter übergeben.

Was hier nicht stimmen kann, ist die Meldung, dass nur zwei erwartet werden. Es müssten drei erwartet werden, und die werden ja auch übergeben.
pcos
User
Beiträge: 16
Registriert: Dienstag 3. April 2007, 14:21

Montag 25. August 2008, 11:14

Hallo,

schau mal nach, ob

- in dem "usf." (Zeile 8) noch eine __init__ erscheint, die die Version aus Z. 4 überschreibt
- die ganze Klasse ClProject nicht irgendwo überschrieben wird.
Flo668
User
Beiträge: 39
Registriert: Mittwoch 23. Juli 2008, 10:41

Montag 25. August 2008, 15:17

Ja, ich habe da noch eine __init__ ich wollte eben mit einem überladenen Konstruktor arbeiten- geht das in Python nicht?
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Montag 25. August 2008, 15:29

Zumindest überschreibst du mit einer einfachen Definition den ersten. Was für einen Mehrwert erwartest denn davon? IMHO kein gut lesbarer Stil.
Da dürfte jedenfalls dein Problem liegen.
Flo668
User
Beiträge: 39
Registriert: Mittwoch 23. Juli 2008, 10:41

Montag 25. August 2008, 15:52

Überladene Konstruktoren sind super praktisch, aber dann werde ich mich in Python eben davon verabschieden müssen. Danke!!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Montag 25. August 2008, 16:16

Flo668 hat geschrieben:Überladene Konstruktoren sind super praktisch, aber dann werde ich mich in Python eben davon verabschieden müssen. Danke!!
Verabschieden könntest du dich vom Begriff "Konstruktor", denn der trifft hier nicht exakt und wird von den Pythologen eher nicht verwendet.

Was du willst, ist die Überladung der __init__()-Methode und davon musst du dich nicht verabschieden. Du musst nur in der __init__()-Methode auch die __init__()-Methode der vererbenden Klasse explizit aufrufen.

Code: Alles auswählen

class A(object):

    def __init__(self,x):
        self.x = x

class B(A):

    def __init__(self,x,y):
        A.__init__(self,x)
        self.y = y
Flo668
User
Beiträge: 39
Registriert: Mittwoch 23. Juli 2008, 10:41

Montag 25. August 2008, 16:21

Ach so. Ich habe das eben gemacht, wie ich es aus anderen OO- Sprachen gewöhnt war. Danke nochmals !
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 25. August 2008, 17:03

Flo668 hat geschrieben:Überladene Konstruktoren sind super praktisch
Dann solltest du dir mal Generic Methods ansehen (die es in Python gibt), das setzt noch eins auf Overloading drauf indem nicht nach den Typen der Aufruft dispatched wird sondern quasi nach belibigen Kriterien. Etwa wenn der erste Parameter ein String ist, der ein "ö" enthält. Oder eben quasi beliebige andere Regeln.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
lunar

Montag 25. August 2008, 17:31

Flo668 hat geschrieben:Ach so. Ich habe das eben gemacht, wie ich es aus anderen OO- Sprachen gewöhnt war. Danke nochmals !
Zumindest in Java, C# und C++ muss man meines Wissens den Konstruktor der Vaterklasse ebenfalls explizit aufrufen.
BlackJack

Montag 25. August 2008, 20:14

@Flo668: Ich möchte noch einmal nachfragen, was denn so superpraktisch am überladen ist? In den meisten Fällen, die ich zum Beispiel aus Java kenne, kann man das in Python mit "default" Argumenten lösen.

Und da Du andere OO-Sprachen erwähnst: In Python gibt es kein "private" und Deine vielen doppelten Unterstriche riechen nach Missbrauch dieses Mechanismus. Wenn Du "private" Attribute haben möchtest, reicht ein einzelner führender Unterstrich um dies zu kennzeichnen.
barfoos
User
Beiträge: 25
Registriert: Dienstag 29. Juli 2008, 09:46

Dienstag 26. August 2008, 08:57

BlackJack hat geschrieben: Und da Du andere OO-Sprachen erwähnst: In Python gibt es kein "private" und Deine vielen doppelten Unterstriche riechen nach Missbrauch dieses Mechanismus. Wenn Du "private" Attribute haben möchtest, reicht ein einzelner führender Unterstrich um dies zu kennzeichnen.
Das ist mir neu. Kannst du das bitte näher erläutern?

Danke und gruß
barfoos
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dienstag 26. August 2008, 09:26

barfoos hat geschrieben:
BlackJack hat geschrieben: Und da Du andere OO-Sprachen erwähnst: In Python gibt es kein "private" und Deine vielen doppelten Unterstriche riechen nach Missbrauch dieses Mechanismus. Wenn Du "private" Attribute haben möchtest, reicht ein einzelner führender Unterstrich um dies zu kennzeichnen.
Das ist mir neu. Kannst du das bitte näher erläutern?
``_name`` steht für: "Implementationsdetail, nicht Teil der API, nicht anfassen, wenn man nicht weiß was man tut". ``__name`` steht für "Name-Mangle, benenne den Namen in _Klassenname_name`` um, um Namenskollisionen zu vermeiden. Solche sind aber ziemlich selten und daher wird sowas auch entsprechend fast nie verwendet.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Dienstag 26. August 2008, 09:31

In Python gibt es keine privaten Attribute - da ist nicht viel zu erläutern. Es gibt halt keine. Es gibt so eine Art "Pseudoprivatisierung" durch zwei vorangestellte Unterstriche. Auf diese Attribute kann dann nicht "direkt", d.h. nicht über diesen Bezeichner, aber über ein Hintertürchen dann doch zugegriffen werden, so dass auch solche Attribute nicht "privat" sind in dem Sinne, dass ein echter Zugriffsschutz besteht.

Da dem so ist, genügt es folglich auch, nur einen Unterstrich zu verwenden, um so - gemäß Konvention - anzuzeigen, dass dieses Attribut als privat anzusehen ist und man möglichst die Finger davon lassen sollte.

Da sich ein Quelltext mit Bezeichnern, die mit zwei führenden Unterstrichen beginnen, insgesamt eher schlecht liest - vor allem, wenn man dieses Hintertürchen nutzt (siehe dazu das Tutorial) - und es letztlich eh keine echte Privatisierung bringt, kann man es auch gleich lassen und sich auf einen Unterstrich beschränken.
Antworten