Deep reload?

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
Krauzi
User
Beiträge: 77
Registriert: Montag 22. Oktober 2007, 18:06
Kontaktdaten:

Servus leute, ich arbeite gerade mit der Python C API und das klappt auch ganz gut, jedoch möchte ich eine reload funktion einbauen. Die klappt anscheinend nur begrenzt, sprich: Es lädt nicht die submodule nach!
Ich habe etwa folgende Ordnerstruktur:

Code: Alles auswählen

+--GHost++
|   |
|   +--python
|   |   |
|   |   +--__init__.py
|   |   |
|   |   +--test.py]

durch import(python) wird alles ordnungsgemäß aufgerufen, die funktionen werden korrekt registriert. Jetzt lasse ich python reloaden, wodurch jedoch nur die "__init__.py" reloadet wird, nicht aber test.py. Ich habe es sogar schon mit del python, anschließendem import und reload von python versucht... jedoch ohne Erfolg. Ich habe gelesen, dass es bei "Ipython" (ka was das ist) eine deep reload funktion gibt, ich brauche allerdings eine möglichkeit mit "offiziellen" funktionen der python > 3.x libs.
Was ich noch entdeckt habe war ein import von sys und hier ein sys.module.clear() jedoch denke ich, dass das nur mit sys modulen klappt...

Wie also kann ich einen "deep reload" durchführen bzw wie kann ich meine reste der "test.py" korrekt löschen?

MfG Krauzi

P.s.: die __init__.py macht folgendes:

Code: Alles auswählen

import test
test.init()
inhalt test:

Code: Alles auswählen

import GHost

def init():
    GHost.registerHandler("PlayerJoin", onPlayerJoin) #GHost ist eine mit der Python C API erstelltes Modul; 
                                                      #hier wird auf das Event "PlayerJoin" meine Funktion onPlayerJoin registriert

def onPlayerJoin(player):
    if player.getName() == "Krauzi":
        player.setIsAdmin(True)
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Das mit sys.modules könntest du mal versuchen, aber wozu brauchst du das überhaupt? o_O
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Ruf doch einfach einen reload auf test in deiner __init__.py. Übrigens sollte dir bewusst sein, dass du dadurch nie so einfach alle Reste deiner Module löschen kannst. Wenn irgendwo noch Referenzen auf Teile deines Moduls existieren, bleiben diese weiterhin bestehen.

Code: Alles auswählen

>>> import foo 
>>> from foo import bar 
>>> foo.bar(), bar() 
23, 23 
>>> reload(foo) # ändere vorher etwas in foo.py 
>>> foo.bar(), bar() 
42, 23
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Es gibt in Python keine Submodule. Jedes Modul steht unabhängig für sich. Einige haben nur "zufällig" den selben Namenspräfix. Da übrigens jedes Modul beim Laden beliebige Seiteneffekte haben kann, halte ich es generell nicht für möglich, durch "reload" einen definieren Systemzustand zu erhalten. Besser ist es IMO, wie die meisten Web-Rahmenwerke vorzugehen und den Code in einem eigenen Prozess zu laden und dann diesen komplett wegzuschmeißen, einen neuen Prozess abzuspalten und wieder von vorne zu beginnen. Da Python keine Sandbox hat, lässt dich sauberes entladen und zurücksetzen eines Systems nur mit Hilfe von Betriebssystem-Prozessen realisieren. Wenn das Programm jetzt mit irgendwem kommunizieren soll, muss das natürlich leider über Prozessgrenzen hinweg erfolgen, aber so ist's dann halt.

Stefan
Krauzi
User
Beiträge: 77
Registriert: Montag 22. Oktober 2007, 18:06
Kontaktdaten:

hm ok, dann muss ich wohl doch eine eigene deep reload funktion coden.

Übrigens:
ein reload in der __init__.py erzeugt einen crash oO.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Krauzi hat geschrieben:Übrigens:
ein reload in der __init__.py erzeugt einen crash oO.
Bei mir nicht.

Code: Alles auswählen

In [1]: import foo # foo/__init__.py importiert foo.test
imported test
imported test

In [2]: reload(foo)
imported test
Krauzi
User
Beiträge: 77
Registriert: Montag 22. Oktober 2007, 18:06
Kontaktdaten:

arbeitest du mit boost::python?
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Das mit dem neu laden geht spätestens dann schief (im Sinne von es wird einfach nicht neu geladen), wenn man es mit Modulen zu tun hat, die nicht in Python geschrieben sind, zumindest unter Plattformen, bei denen diese Module mit `dlopen()` geladen werden.

Wie sma schon sagte, wirklich alles neu laden funktioniert einfach nicht, ohne dass man eben die Prozesse wechselt.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Antworten