Seite 1 von 1
Erben aus einer eigenen Klasse in anderem Modul
Verfasst: Mittwoch 29. November 2006, 18:24
von JR
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
Verfasst: Mittwoch 29. November 2006, 18:29
von Leonidas
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?
Verfasst: Mittwoch 29. November 2006, 18:35
von JR
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)
Verfasst: Mittwoch 29. November 2006, 18:57
von sape
Hmm ist ja strange

Das sollte eigentlich 100% gehen!
lg
Verfasst: Mittwoch 29. November 2006, 19:08
von BlackJack
Liegt die `JRBib` auch im Python-Pfad?
Verfasst: Mittwoch 29. November 2006, 19:12
von JR
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
Verfasst: Mittwoch 29. November 2006, 19:21
von BlackJack
Dann importierst Du da eine andere JRBib. Versuch mal folgendes in dem Modul wo Du das Problem hast:
Wird da die richtige Datei und der richtige Inhalt ausgegeben?
Verfasst: Mittwoch 29. November 2006, 19:31
von JR
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'
Verfasst: Mittwoch 29. November 2006, 19:46
von 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.

Verfasst: Mittwoch 29. November 2006, 20:01
von JR
Ja, aber ist das tragisch?
All meine Module importieren main.pyw, damit ich schnell Tests fahren kann, indem in jedem Mpdul unten
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?
Verfasst: Mittwoch 29. November 2006, 20:20
von Joghurt
JR hat geschrieben:Ja, aber ist das tragisch?
Ja, ist es...
A importiert B importiert C importiert A importiert B importiert C ...
Verfasst: Mittwoch 29. November 2006, 20:24
von JR
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.
Verfasst: Mittwoch 29. November 2006, 20:39
von BlackJack
Gehen wir mal nur von zwei Modulen aus:
Modul A:
Modul B:
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`.
Verfasst: Mittwoch 29. November 2006, 20:40
von sape
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

Verfasst: Mittwoch 29. November 2006, 20:42
von sape
Jack, oh so ist das. Wusste ich garnicht. Was soll man den dagegen machen wenn beide Module Funktionen/Klassen haben die beiden Module haben?
Verfasst: Mittwoch 29. November 2006, 20:57
von JR
Hi!
Okay, dann nehme ich das raus. War eh nur zum komfortableren Testen per Tastendruck
Verfasst: Mittwoch 29. November 2006, 21:01
von 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.
Verfasst: Mittwoch 29. November 2006, 21:04
von JR
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