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:

Code: Alles auswählen

import JRBib
print JRBib.__file__
print dir(JRBib)
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

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?

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:

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`.

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