Gegenteil von Import (Speicherfreigabe) - BoaConstructor

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!

Drei Fragen habe ich und ich würde mich sehr über eine Antwort freuen:

1)
Wenn ich ein Modul oder eine Funktion importiert habe. Wie kann ich das rückgängig machen, um beispielsweise den Namespace wieder zu löschen? Gibt es da nicht einen gegensätzliches Kommando?

2)
Wenn ich eine Funktion in einem Modul nach einem Import verändere, muss ich jedes Mal in der IDE

Code: Alles auswählen

reload(modul)
from modul import funktion 
eingeben, damit die Änderungen auch wirksam werden. Ich verwende den Editor und die Shell der Benutzeroberfläche "Boa Instructor".

Gibt es eine elegantere Art die Änderungen wirksam zu machen?

3)
Kennt sich jemand mit "Boa Instructor" aus? Bin absoluter Einsteiger (was es Python anbelangt). Debugger läuft noch nicht :-( , aber dazu später...


Viele Grüße
JR
cime
User
Beiträge: 152
Registriert: Dienstag 24. Mai 2005, 15:49

hi, JR

1) ja:

Code: Alles auswählen

del name
2) Inwiefern möchtest du eine Funktion nachträglich bearbeiten? Möchtest du Sie im Hauptprogramm neuschreiben / überschreiben?

3)Sorry, kenn ich nicht.

mfg
cime
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hallo!

Es ist so. Beispiel:

Ich habe ein Modul :

Code: Alles auswählen

def test():
      print "Hallo"
und speichere es als hallo.py ab.
Um es nun in der IDE über das kommando test() auslösen zu können,
gebe ich folgendes in der IDE ein:
[/code]
from hallo import test
[/code]
Wenn ich nun test() in der IDE eingebe wird ein "Hallo" ausgegeben.
Nun gehe ich in den Editor und verändere den print-Befehl zu print "Tschüß" und speichere die Datei hallo.py ab.

Wenn ich in der IDE test() eingebe, erscheint immer noch "Hallo"

Erst wenn ich

Code: Alles auswählen

reload(hallo)
from hallo import test
test()
in der IDE eingebe, wird "Tschüß" ausgegeben. Geht das nicht weniger umständlich?

Das Beispiel war natürlich absichtlich sehr kurz. Aber bei längeren Programmmodulen, wäre das nervig.

Bis denn
JR[/code]
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Wenn du ein Modul importiert hast bleibt es im Speicher des Interpreters unverändert solange bis Du eben jenen reload()-Befehl ausführst. Daran ist nichts zu drehen, das ist vor allen Dingen in keiner anderen Interpreter-Sprache anders.

Ein Modul aus dem Namespace zu löschen und dann neu importieren hilft hier auch nicht, da dass Modul als Referenz in sys.modules überlebt, und von da als "cache" nur geholt wird wenn Du es neu importierst.

Um eben jenes neue Parsen und Ausführen zu erzwingen: reload().
--- Heiko.
cime
User
Beiträge: 152
Registriert: Dienstag 24. Mai 2005, 15:49

ein anderer Tip noch:

am besten du arbeitest immer mit kompletten Programmen, da du dort solche Probleme nicht hast, da bei jedem erneuten ausführen das jweilige Modul ja neu geladen wird

mfg cime
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

modelnine hat geschrieben:Wenn du ein Modul importiert hast bleibt es im Speicher des Interpreters unverändert solange bis Du eben jenen reload()-Befehl ausführst. Daran ist nichts zu drehen, das ist vor allen Dingen in keiner anderen Interpreter-Sprache anders.
Das ist nicht nur bei interpretern und VirtualMachines so.
Ich würde sagen das ist in allen formaten so, auch bei PE und ELF.

Stell dir das schreiben in der console als programm vor das du in echzeit schreibst. Was einmal geladen ist lädt sich nicht sinnlos nochmal.
Wäre ja auch höchst unnütz wenn bei jedem "print" das ding anfängt den core neu zu laden.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Ich würde sagen das ist in allen formaten so, auch bei PE und ELF.
Ahemm... Erstens: das hat nix mit Formaten von ausführbaren Dateien zu tun, sondern mit der Speicherverwaltung deines Betriebssystems/der VM, und zweitens: man kann rein theoretisch Änderungen am Code-Segment einschleusen (unter Linux), und zwar:

ELF-Files werden manchmal ge-mmaped, sprich das Codesegement wird mittels der Virtuellen Speicherverwaltung (die eben auch den Swap verwaltet) in den Hauptspeicher von der physikalischen Position auf der Platte gemapped, genauso wie das mit dem Swap-Speicher passiert.

Da das Code-Segment nicht schreibbar ist kannst Du aus dem Programm keine Veränderungen an dem Code-Segment vornehmen die sich auf der Platte wiederspiegeln (es wird also nicht zurückgeswapped), aber wenn Du auf der Platte das Code-Segment veränderst, das Code-Segment (besser gesagt einen Teil, nämlich eine Page, davon) ausswappen lässt (die eben nicht in den Swap muß da sie unverändert auf Platte liegt, was der große Vorteil von dieser Art des Mappings von ausführbaren Dateien in den Hauptspeicher ist), und es dann wieder kurz darauf in den Speicher holst (was das Virtual Memory Management alles für Dich macht) hast Du den Effekt dass sich das Image geändert hat.

Soweit ich weiß blockieren EXT2 und EXT3 (die einzigen Dateisysteme die dieses mmapping von executables unterstützen, auch wieder soweit ich weiß) Änderungen an der ausführbaren Datei (sprich an dem Inhalt ihres Inodes) wenn sie gemapped ist, aber im Prinzip ist es möglich Code so einzuschleusen. Aber auch hier wird der Code sozusagen "neu" geladen.
--- Heiko.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hallo!

Hab gerade entdeckt, dass da doch noch einige Antworten zu meiner Frage eingegangen sind... :oops:

Jedenfalls vielen Dank für die Hinweise, dann lebe ich erst einmal mit diesem Umstand.

Grüße
JR
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hallo nochmals!

Ich habe folgendes Anfängerskript aus der Python-Gepackt (Buch) als lampe.py abgespeichert:

Code: Alles auswählen

class Lampe:
    def __init__(self, helligkeit):
            self.helligkeit = helligkeit
            self.eingeschaltet = 0

    def einschalten(self):
	"""
	schaltet die Lampe ein."""
        if self.eingeschaltet:
                print 'Erst Lampe ausschalten!'
        else:
                self.eingeschaltet = 1
                print 'Die Lampe brennt mit ' + \
                      str(self.helligkeit) + ' Watt.'


    def ausschalten(self):
        if not self.eingeschaltet:  print 'Die Lampe ist schon aus!'
        else:
            self.eingeschaltet = 0
            print 'Die Lampe wurde ausgeschaltet.'

    def neue_Birne(self, watt):
        if self.eingeschaltet:
            print 'Sie muessen die Lampe erst ausmachen!'
        else:
            self.helligkeit = watt
            print 'Die Lampe hat eine neue Birne mit ' +\
                  str(watt) + ' Watt.'
Initalizieren bzw. laden tue ich das Modul mit

Code: Alles auswählen

import lampe
from lampe import *
Wenn ich nun in einer der Methoden etwas ändere und diese Änderungen auch beim Verwenden meines Scripts in der Shell wirksam werden sollen, wie gehe ich da vor?

Folgendes klappt nicht:

Code: Alles auswählen

del Lampe
from lampe import *
Entschuldigt diese Anfängerfrage... aber irgendwie komme ich nicht auf die richtige Kommandoreihenfolge :-(

Viele Grüße
JR
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Wenn du ein Skript aus der Shell ausfuehrst, sollte

Code: Alles auswählen

from lampe import *
reichen. Denn bei jeder Ausfuehrung des Skripts wird der Python-Interpreter und somit die Module wieder komplett neu geladen.

Code: Alles auswählen

del lampe
in der ersten Zeile sollte wohl eine Fehlermeldung verursachen, sowas wie
NameError: name 'lampe' is not defined
da du versuchst, ein noch nicht geladenes Modul zu loeschen.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

JR hat geschrieben:Wenn ich eine Funktion in einem Modul nach einem Import verändere, muss ich jedes Mal in der IDE

Code: Alles auswählen

reload(modul)
from modul import funktion
eingeben, damit die Änderungen auch wirksam werden. Ich verwende den Editor und die Shell der Benutzeroberfläche "Boa Instructor".
Hi JR!

Wenn "Boa Constructor" eine "Interaktive Python-Shell" eingebaut hat, dann verhält sich die wahrscheinlich gleich wie eine "Interaktive Python-Shell", die man mit "python" starten kann. Du wirst wahrscheinlich um die oben genannten Befehle nicht herum kommen.

Warum brauchst du das überhaupt? Baue in dein Programm eine "Testfunktionen" ein und führe das Programm immer wieder neu aus.

Wahrscheinlich kann man bei "Boa Constructor" auch Haltepunkte setzen und das Programm gezielt an einer Stelle unterbrechen um von da aus das Programm zu debuggen. Wenn nicht, dann würde ich auf eine bessere IDE umsteigen. Probier doch mal WingIDE. http://wingware.com

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hallo Rebecca und Gerold!

Zunächst zu Rebecca:
Die Meldung

Code: Alles auswählen

NameError: name 'lampe' is not defined

ist tatsächlich aufgetreten.

---

Leider sitze ich grad unter gesundem Zeitdruck und kurz vor der Abgabe an meiner Studienarbeit. Ab Montag kann ich mich nochmals ausführlich mit dem "Problem" befassen und ggf. eine genauere Beschreibung abgeben...

Gerold, danke für den Tipp. Ich muss sagen, dass ich Boa-Instructor nicht mehr verwende. Bin vorerst auf die von Michael Weigend erwähnte Umgebung PythonWin umgestiegen. Boa-Instructor ist mitunter für das Designen einer Benutzeroberfläche mit Frames vorgesehen, doch
ich gedenke meine Benutzeroberfläche wahrscheinlich eh komplett über XHTML und CSS in Zope und Plone zu realisieren.
Ist zwar anfangs ziemlich kompliziert, aber ich glaube es lohnt sich die Technik der TAL(ES) und METAL's zu erlernen.

Also dann
viele Grüße
JR
Kompottkin
User
Beiträge: 21
Registriert: Sonntag 26. Februar 2006, 03:09
Wohnort: Penzberg
Kontaktdaten:

JR hat geschrieben:Initalizieren bzw. laden tue ich das Modul mit

Code: Alles auswählen

import lampe
from lampe import *
Die Anweisung from <Modul> import * sollte man in der Regel nicht verwenden. import <Modul> allein sorgt für weniger Verwirrung.
Wenn ich nun in einer der Methoden etwas ändere und diese Änderungen auch beim Verwenden meines Scripts in der Shell wirksam werden sollen, wie gehe ich da vor?
Würdest Du import lampe (und nicht from lampe import *) verwenden und auf die Klasse unter dem Namen lampe.Lampe (nicht Lampe) zugreifen, so würde eine einzige Zeile reichen:

Code: Alles auswählen

reload(lampe)
Antworten