Erben aus einer eigenen Klasse in anderem Modul

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
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hallo!

Mich wundert etwas.
Ich habe ein Modul JRBib.py mit einer Klasse class Liste.

Wenn ich in einem anderen Modul folgendes mache:

Code: Alles auswählen

import JRBib
class Flightlist(JRBib.Liste):
    def __init__(self,bla bla):
        pass
dann bekomme ich folgenden Fehler

Code: Alles auswählen

    class Flightlist(JRBib.Liste):
AttributeError: 'module' object has no attribute 'Liste'
Bei irgendwelchen wx-Klassen funktioniert das Vererben doch genauso, oder?

Viele Grüße
Jamil
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Doch, das müsste nochmalerweise so gehen (bis auf das "bla bla" kein gültiger variablenname ist und eine Exception triggern würde). Wie sieht denn dein JRBib aus?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hi Leonidas!

Die JRBib ist ziemlich groß. Das JR kommt von meinen Initialien und das Bib von "Bibliothek"

Verkürzt sieht es so aus.
JRBib.py

Code: Alles auswählen

#!/Python24/python.exe
# -*- coding: iso-8859-1 -*-
# File: JRBib.py
import wx
import wx.lib.mixins.listctrl as listmix
class Liste(wx.ListCtrl, 
            listmix.ListCtrlAutoWidthMixin, 
            listmix.ColumnSorterMixin,
            listmix.TextEditMixin):
                
    def __init__(
                self,
                MDIPFrm,
                dialog,
                panel, 
                pos=wx.DefaultPosition, 
                size=wx.DefaultSize, 
                style=wx.LC_REPORT|wx.LC_HRULES|wx.LC_VRULES|wx.LC_SMALL_ICON):

        wx.ListCtrl.__init__(self, panel, -1, pos, size, style=wx.LC_REPORT|wx.LC_HRULES|wx.LC_VRULES)
        listmix.ListCtrlAutoWidthMixin.__init__(self)
Und in einem anderen Modul heißt es

Code: Alles auswählen

#!/Python24/python.exe
# -*- coding: iso-8859-1 -*-
# File: kmmSTL.py
import JRBib

class Flightlist(JRBib.Liste):
    def __init__(
                self,
                MDIPFrm,
                dialog,
                panel,
                pos,
                size):
        JRBib.Liste.__init__(self, MDIPFrm, dialog, panel, pos, size) 
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Hmm ist ja strange :? Das sollte eigentlich 100% gehen!

lg
BlackJack

Liegt die `JRBib` auch im Python-Pfad?
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hi BlackJack,

das nicht direkt, aber ich kann sie tadellos importieren und Instanzen von Klassen aus ihr erstellen oder irgendwelche Prozeduren rufen.

Da ich mit Eclipse und dem Plugin PyDEV für Pythonentwicklung prgrammiere kann es sein, dass Eclipse bzw. PyDEV das mit dem PATH erledigen.
Gruß
Jamil
BlackJack

Dann importierst Du da eine andere JRBib. Versuch mal folgendes in dem Modul wo Du das Problem hast:

Code: Alles auswählen

import JRBib
print JRBib.__file__
print dir(JRBib)
Wird da die richtige Datei und der richtige Inhalt ausgegeben?
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Es ist verflixt.

Wenn ich in meinem Modul, welches JRBib importiert keine Klasse Flightlist deklariere, dann wird mir folgendes ausgegeben, wobei wesentlich ist, dass 'Flightlist' auftaucht.

Code: Alles auswählen

D:\dateien\Programmieren\Workspace\KMManager\src\JRBib.pyc
['__builtins__', '__doc__', '__file__', '__name__', 'datetime', 'listmix', 'os', 'sys', 'time', 'wx']
D:\dateien\Programmieren\Workspace\KMManager\src\JRBib.pyc
['Date_German_2_SQL', 'Date_SQL_2_German', 'DialogNoteBook', 'DialogOkCancel', 'DivCodedFile', 'DlgNoRight', 'DlgOkCancel', 'Fenster', 'Flightlist', 'GetDateTime', 'GetMySQLDateByDatePickerCtrl', 'JRButtons', 'Liste', 'LoginDialog', 'MakeTimeHHMMTry', 'Msg', 'MySplashScreen', 'RecList', 'SetDatePickerCtrlbyMySQLDate', 'SetFrameIcon', 'WriteDataFile', '__builtins__', '__doc__', '__file__', '__name__', 'datetime', 'kmmBib', 'kmmImages', 'listmix', 'main', 'os', 'printDir', 'show_progressdiag', 'subprocess', 'sys', 'time', 'timediff', 'timesum', 'wx', 'yPos']
Wenn ich nun in meinem Modul, welches JRBib importiert
folgednes drin habe

Code: Alles auswählen

class Flightlist(JRBib.Liste):
    def __init__(
                self,
                MDIPFrm,
                dialog,
                panel,
                pos,
                size):
        JRBib.Liste.__init__(self, MDIPFrm, dialog, panel, pos, size)
dann bekomme ich folgendes

Code: Alles auswählen

D:\dateien\Programmieren\Workspace\KMManager\src\JRBib.pyc
['__builtins__', '__doc__', '__file__', '__name__', 'datetime', 'listmix', 'os', 'sys', 'time', 'wx']
Traceback (most recent call last):
  File "D:\dateien\Programmieren\Workspace\KMManager\src\kmmSTL_New.py", line 6, in ?
    import JRBib
  File "D:\dateien\Programmieren\Workspace\KMManager\src\JRBib.py", line 10, in ?
    import main
  File "D:\dateien\Programmieren\Workspace\KMManager\src\main.pyw", line 24, in ?
    import kmmHFB
  File "D:\dateien\Programmieren\Workspace\KMManager\src\kmmHFB.py", line 11, in ?
    import kmmSTL_New
  File "D:\dateien\Programmieren\Workspace\KMManager\src\kmmSTL_New.py", line 17, in ?
    class Flightlist(JRBib.Liste):
AttributeError: 'module' object has no attribute 'Liste'
BlackJack

Äh, sehe ich da einen zirkulären Import?

kmmSTL_New.py importiert JRBib.py,
das importiert main.pyw,
das importiert kmmHFB.py
und das importiert das erste Modul kmmSTL_New.py

Zeit sich Gedanken über den grundsätzlichen Entwurf zu machen. :-)
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Ja, aber ist das tragisch?

All meine Module importieren main.pyw, damit ich schnell Tests fahren kann, indem in jedem Mpdul unten

Code: Alles auswählen

if __name__ == '__main__':
    main.main()  
steht.
Damit hatte ich bisher (seit drei Monaten) auch noch nie ein Problem.
Meinst du, dass es daran liegt? Dürfte doch eigentlich nicht sein, oder?
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

JR hat geschrieben:Ja, aber ist das tragisch?
Ja, ist es...

A importiert B importiert C importiert A importiert B importiert C ...
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Das wundert mich, denn ich erinnere mich an folgendes von Gerold und BlackJack:

http://www.python-forum.de/topic-6204.h ... eit+import

Lest euch das mal durch. So wie ich es verstanden habe, wird ein Modul maximal einmal importiert. Bei jedem Importversuch wird geprüft, ob ein Modul bereits importiert wurde und wenn ja, dann werden nur die Namensräume aktualisiert.
BlackJack

Gehen wir mal nur von zwei Modulen aus:

Modul A:

Code: Alles auswählen

import B

x = B.Spam()
Modul B:

Code: Alles auswählen

import A

class B:
    pass
Wir starten Modul A als Programm. Modul A wird in Bytecode übersetzt im Modulcache unter dem Namen __main__ (!) eingetragen und dann ausgeführt.

Es geht los mit der ersten Zeile: ``import B``. Modul B wird in Bytecode übersetzt und im Modulcache eingetragen und dann ausgeführt.

Die Ausführung von B beginnt mit der ersten Zeile: ``import A``. Das Modul ist *nicht* im Modulcache weil es jetzt A heisst und nicht __main__, es wird also in Bytecode übersetzt und als A im Modulcache eingetragen und dann ausgeführt.

Es geht los mit der ersten Zeile: ``import B``. B gibt's im Modulcache, der ``import`` macht also nichts weiter und es geht mit ``x = B.Spam()`` weiter. Aber dummerweise wurde in Modul B die ``class`-Definition noch gar nicht ausgeführt: `AttributeError`.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

JR denn thread hatte ich damals auch gelesen und auch so verstanden wie du. Daher wundere ich mich jetzt auch das es dabei Probleme geben sol :?
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Jack, oh so ist das. Wusste ich garnicht. Was soll man den dagegen machen wenn beide Module Funktionen/Klassen haben die beiden Module haben?
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hi!

Okay, dann nehme ich das raus. War eh nur zum komfortableren Testen per Tastendruck
BlackJack

Man sollte keine zirkulären Modulabhängigkeiten erzeugen. Wenn Modul A und B sich gegenseitig brauchen, dann stellt sich die Frage warum der Quelltext nicht in einem Modul steht. Der Sinn Code in Module aufzuteilen besteht ja gerade darin, dass man Quelltext in sinnvollen, in sich geschlossenen Einheiten zusammenfasst.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hi!

Ja, da hast du natürlich vollkommen recht. Ich kann die Frage von XtraNine dennoch auch verstehen. Denn wenn man schnell entwickelt und dieses Problem der zirkulären Importe gar nicht als Problem erkennt, entstehen solche Abhängigkeiten schnell.

Habe heute wie so oft etwas dazu gelernt.

Danke!
Jamil
Antworten