@Sorry cofi, bin ich es denn, der damit ständig anfängt und der das dann weiter austreten will? Hab ich das etwa geschrieben?
@Alfons Mittelmeyer: Das was Du da schreibst hat nichts mit dem ja nun bereits gelösten Problem zu tun. Und Probleme die man durch `compile()` und `exec` bekommt behebt man ganz einfach in dem man `compile()` und `exec` nicht benutzt.
Und mit Speicherproblemen hat das zwar auch zu tun aber auch mit völlig unsinnigen Forderungen und mit erheblichen Sicherheitsrisiken. Mal schon darüber nachgedacht, welche Sicherheitsrisiken import birgt?
Davon abgesehen hat kbr auch nicht unrecht, wenn auch nicht alles stimmt, denn was del macht und der Garbage Collector ist genau definiert. Aber del brauche ich nicht zu benützen, denn der Garbage Collector erledigt bereits alles zu meiner Zufriedenheit. Man braucht ihm nur die Gelegenheit dazu zu geben.
Und anscheinend wollen ihn die meisten gar nicht erst ranlassen. Im Mainscript etwa steht ein mainloop. Da steht es auch mit recht, aber dadurch kann das Script nicht zu Ende kommen und der Garbage Collector auf das im Mainscript Definierte auch nicht wirksam werden.
Anderes importiert man als Module und damit ist das global definiert und bleibt bis zum Programmende bestehen und auch da kommt dann der Garbage Collector wieder nicht zum Zuge.
Auf das, was der Garbage Collector zugreift, ist lokal Definiertes. Lokal Definiertes bekommt man, indem man eine Funktion schreibt und die dann aufruft. Und wenn die Funktion dann zuende ist, werden die lokalen Variablen und Objekte entsorgt, sofern sie nicht an etwas Global Definiertes gebunden wurden.
Wahrscheinlich kein großes Geheimnis für alle.
Idealerweise sollte man so eine Funktion schreiben:
Code: Alles auswählen
def load_script(filename):
exec(compile(open(filename, "r").read(), filename, 'exec'))
Hier wird nämlich ein Script geladen und ausgeführt und dann dem Garbage Collector übergeben. Wennn man nicht will, dass dieses Script auf etwas im Mainscript zugreifen soll, legt man diese Funktion am Besten in ein anderes Modul, welches man dann importiert.
Wenn man nicht will, dass so ein Script auf irgend etwas in diesem Modul zugreifen soll, schreibt man eben auch nichts anderes rein. Wenn man nicht will, das so ein Script load_script aufruft, dann kann man auch load_script aus dem globalen Namensraum dieses Modules beseitigen.
Wenn man nicht will dass so ein Script import und andere sicherheitsrelevanten Builtin Funktionen aufruft, kann man auch diese beseitigen.
Wenn man dagegen import benutzt, kann man gar nichts. Ein mit import importiertes Modul ist erstens global und kann zweitens tun, was ihm gefällt. Das aber gefällt mir gar nicht. Dann was etwas tun darf oder nicht darf will ich bestimmen und das nicht irgendeinem importierten Skript überlassen.
Und was ich auch nicht einsehe ist, dass man so unsinnige Sachen von mir will, wie dass ich import benutzen soll für Skripte, die außer Funktionsaufrufen nichts enthalten. Dass ich einfach nur dafür Module verbraten soll, damit direkt beim ersten Import Funktionsaufrufe ausgeführt werden, während die Module dann völlig leer sind und nichts mehr darüber hinaus enthalten.
Und wenn es ganz blöd kommt und jemand dann hundert Icons ungeschickt lädt, muss ich um eine GUI Seite zu laden, dann auch mal hundert Module verbraten. Da werden die sich ganz bestimmt sehr freuen, die dann aus Ihren Verzeichnissen ein paar Tausend Modulfiles immer hinterher herauslöschen dürfen.
Außerdem gibt es auch komplexere Seiten, die wirklich mal 50 Scripte, also 50 Module brauchen. Und manche enthalten dann auch noch Code. Für komplexere Seiten nimmt man bei HTML etwa Java Script. Da nimmt man dann eben Python. Und dann bleibt auch global definierter Garbage übrig, der nicht im Garbage Collector landet, wie er es eigentlich tun sollte.
Also das Ansinnen, dass ich import benutzen sollte, finde ich absolut unsinnig.