Sag ich ja, mach doch einfach mal weiter und veröffentliche dein DynTkInter, dann können wir weiter sehen...
bzw. du weißt, was "Garbage Collection" ist oder?
-> https://de.wikipedia.org/wiki/Garbage_Collection
'command' zwei Argumente übergeben?
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Ich habe jetzt keine Luste die letzten Seiten alle noch einmal durchzugucken, aber BlackJack und andere haben Dir zig Fakten bezüglich Python allgemein und CPython im speziellen dargelegt, die sehr wohl zeigen, dass ``del`` in dem Kontext sinnlos ist.Alfons Mittelmeyer hat geschrieben:@Hyperion Ich habe überhaupt nichts substantiell Relevantes und Belegtes gegen die Verwendung von del erfahren, nur Vermutungen, dass man das wahrscheinlich nie braucht.
Es sind nicht *einige*, sondern die *aller meisten*! Genau das meinte ich mit gegen den Strom schwimmen - aber wenn Du nicht einmal in der Lage bist zu erkennen, dass Du dies tust, dann ist Dir nicht zu helfen und Du gehörst dann auch nicht zu den Genies sondern zum Komplement dieser GruppeAlfons Mittelmeyer hat geschrieben: Es spricht überhaupt nichts gegen die Verwendung von del. Außer dass einige dieses nicht tun, weil sie es bei ihren Programmen nicht brauchen. Wenn sie es nicht brauchen, dann habe ich überhaupt nichts dagegen, dass sie es nicht verwenden.
Viel Spaß noch beim Querulieren - ich denke der halbwegs aufmerksame stumme Mitleser oder zukünftiger Thread-Archäologe wird mittlerweile kapiert haben, dass Deine Idee unsinnig ist. Mehr müssen wir nicht erreichen als Regulars
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Ja die Garbage Collection löscht Garbage, aber fängt nicht an Deine Funktionen zu löschen, die Du nicht mehr brauchst, aber einfach nicht durch del als Garbage kennzeichnen willst.jens hat geschrieben: bzw. du weißt, was "Garbage Collection" ist oder?
-> https://de.wikipedia.org/wiki/Garbage_Collection
Man muss Garbage nicht explizit als solchen kennzeichnen. Python zählt die Referenzen auf ein Objekt automatisch mit. Wenn der Referenzzähler auf Null steht, d.h. wenn kein Bezeichner mehr auf das Objekt verweist, dann sieht Python es als unerreichbar für den Programmierer an und gibt es daher zum Löschen frei.
Das Aufrufen von `del` führt dabei auch nicht zwangsläufig zum Löschen des Objektes. Es verringert lediglich den besagten Referenzzähler um eine Einheit, da die Verbindung zwischen Bezeichner und Objekt gekappt wird. Falls der Zähler dadurch auf Null steht, dann kann das Objekt gelöscht werden, andernfalls aber lebt das Objekt munter weiter. Bitte `del` daher keinesfalls so ansehen, dass hiermit unmittelbar eine Art Destruktor für das Objekt aufgerufen würde - diese Annahme ist schlichtweg falsch.
Also nochmal ganz deutlich: Mit `del` werden lediglich Referenzen gelöscht. Ein Löschen des Objektes an sich ist nur eine "zufällige" Auswirkung, wenn keine Referenzen mehr für das Objekt bestehen und wenn der Python-Interpreter hierdurch "meint", ein Löschen durchführen zu müssen. Wann der Interpreter dies tut bzw ob er dies überhaupt irgendwann mal vor dem Interpreter-Shutdown tut, ist absolut nicht vorhersehbar.
Das Aufrufen von `del` führt dabei auch nicht zwangsläufig zum Löschen des Objektes. Es verringert lediglich den besagten Referenzzähler um eine Einheit, da die Verbindung zwischen Bezeichner und Objekt gekappt wird. Falls der Zähler dadurch auf Null steht, dann kann das Objekt gelöscht werden, andernfalls aber lebt das Objekt munter weiter. Bitte `del` daher keinesfalls so ansehen, dass hiermit unmittelbar eine Art Destruktor für das Objekt aufgerufen würde - diese Annahme ist schlichtweg falsch.
Also nochmal ganz deutlich: Mit `del` werden lediglich Referenzen gelöscht. Ein Löschen des Objektes an sich ist nur eine "zufällige" Auswirkung, wenn keine Referenzen mehr für das Objekt bestehen und wenn der Python-Interpreter hierdurch "meint", ein Löschen durchführen zu müssen. Wann der Interpreter dies tut bzw ob er dies überhaupt irgendwann mal vor dem Interpreter-Shutdown tut, ist absolut nicht vorhersehbar.
Ergänzend zu snafu's Beitrag: Überall wo Python steht, müsste CPython stehen, denn die Speicherverwaltung von anderen Python-Implementierungen kann durchaus auch anders als mit Referenzzählern gelöst werden. Ist bei Jython beispielsweise der Fall wo die Speicherverwaltung der JVM benutzt wird, die anders funktioniert.
@jens: +1. Am besten in einer Schleife. Mit GOTO.
@jens: +1. Am besten in einer Schleife. Mit GOTO.
Ganz genau. Die einzige Garantie, die `del` einem gibt, ist das besagte Lösen der Verbindung zwischen Bezeichner und Objekt bzw Entfernen des Bezeichners aus dem *Namensraum*, nicht aber aus dem Speicher. `del` als Speicherverwaltung zu benutzen ist definitiv *nicht* die Idee hinter `del`.BlackJack hat geschrieben:Ergänzend zu snafu's Beitrag: Überall wo Python steht, müsste CPython stehen, denn die Speicherverwaltung von anderen Python-Implementierungen kann durchaus auch anders als mit Referenzzählern gelöst werden. Ist bei Jython beispielsweise der Fall wo die Speicherverwaltung der JVM benutzt wird, die anders funktioniert.
Ich habe jetzt mal ein paar Seiten zurückgeblättert, um den Kontext besser zu verstehen: Ich finde die Idee, größere nicht benötigte Bereiche wieder freizugeben, keinesfalls verkehrt. Nur ist `del` leider das falsche Werkzeug für diese Idee. Wie bereits erwähnt, kann es sein, dass die Objekte hinter den mit `del` angesprochenen Bezeichner trotzdem bis kurz vor Ende der Python-Sitzung im Speicher verbleiben. Und dann werden sie genau so im Verlauf des Interpreter-Shutdowns gelöscht wie es auch ohne die Nutzung von `del` passiert wäre.
Und wenn man denkt, dass `del` zur Speicherfreigabe sinnvoll genutzt werden kann, dann möge er mir doch mal die entsprechende Stelle in der Python-Dokumentation zeigen. Die muss ich nämlich bisher wohl übersehen haben...
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Solange ein globaler Name auf ein Objekt verweist, geht der Referenzähler nicht auf Null. Also ohne Neuzuweisung des Namen oder del des Namens kann das Objekt nicht verschwinden. Ein globaler Name ist nämlich auch eine Referenz auf das Objekt. Also kann ohne dieses das Objekt nicht Garbage werden.snafu hat geschrieben:Man muss Garbage nicht explizit als solchen kennzeichnen. Python zählt die Referenzen auf ein Objekt automatisch mit. Wenn der Referenzzähler auf Null steht, d.h. wenn kein Bezeichner mehr auf das Objekt verweist, dann sieht Python es als unerreichbar für den Programmierer an und gibt es daher zum Löschen frei.
Das gilt für globale Namen genau so wie für lokale Namen. Lokale Referenzen werden dann abgeräumt, wenn die Ausführung im lokalen Namensraum (z.B. in der Funktion) abgeschlossen wurde. Bei globalen Namen passiert dies nach Abarbeitung von allem, was im Kontext des jeweiligen Moduls passiert. Globale Referenzen leben für gewöhnlich länger. Man räumt üblicherweise *nicht* manuell mittels `del` ab, sondern dies geschieht automatisch nach Verlassen des jeweiligen Namensraumes. Schau dir gängige Python-Programme an, dann siehst du es.Alfons Mittelmeyer hat geschrieben:Solange ein globaler Name auf ein Objekt verweist, geht der Referenzähler nicht auf Null. Also ohne Neuzuweisung des Namen oder del des Namens kann das Objekt nicht verschwinden. Ein globaler Name ist nämlich auch eine Referenz auf das Objekt. Also kann ohne dieses das Objekt nicht Garbage werden.
Wenn man natürlich auf irgendwelche wirschen Ideen kommt und z.B. meint, man müsste eine Liste mit 3 Milliarden Elementen in einem langlebigen Namensraum halten, dann könnte man durchaus auf die Idee kommen, `del` anzuwenden. Aber genau das vermeidet man üblicherweise durch entsprechend intelligente Programmierung mittels Generatoren, Erzeugung speicherintensiver Objekte erst bei Anforderung, usw.
Beispiel: Bei einer extrem großen Tabelle könnte man in einer GUI tatsächlich nur Ausschnitte aus dem zugrunde liegenden Datenbstand laden, weil der Benutzer sehr wahrscheinlich nicht den kompletten Inhalt ansehen möchte. Dann würde man ein grafisches Element als Ansicht implementieren und diese Ansicht bei Scroll-Aktionen aktualisieren. Aber auch da wird nicht explizit etwas mit `del` gelöscht, sondern der Ansicht wird einfach ein neuer Ausschnitt übergeben und dieser Abschnitt wird durch Neuzeichnen des GUI-Elements neu gerendert.
Ein Namensraum mit tausenden von Funktionen, wie zwischenzeitlich von dir erdacht, ist auch arg konstruiert. Sowas gliedert man normalerweise hinter Module, von denen man nicht zwangsläufig alle gleichzeitig laden muss. Und selbst wenn es doch mal der Fall sein sollte, dass ein umfangreiches Programm die komplette Funktionalität von zig Bibliotheken benötigt, dann käme Python immer noch gut damit klar. Es ist schlichtweg Bullshit, dass man damit auch nur annähernd an die Grenzen der Speicherkapazität seines Rechners käme.
Das Einzige, das man ab einem bestimmten Punkt bemerken könnte, ist die Ladezeit umfangreicher Programme. Da hilft dann aber auch kein `del`, sondern höchstens das phasenmäßige Laden bestimmter Programmteile auf Abruf. Wenn die Programmabschnitte einmal im Speicher initialisiert wurden, dann machen sie normalerweise keine Probleme mehr. Du scheinst wirklich den Speicherbedarf von Programmcode stark zu überschätzen. Oder aber du verwechselt den eigentlichen Programmcode mit dem, was möglicherweise zur Laufzeit in die verschiedenen Datenstrukturen reingesteckt wird. Das sind aber zwei verschiedene Paar Schuhe.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Also, globale Referenzen werden beseitigt, wenn man den jeweiligen Namensraum verläßt? Und wenn man dann später in diesen Namensraum zurückkommt? Sind sie wirklich nicht mehr da? Wie meinst Du das? Kannst Du das mit einem kleinen Beispiel belegen?snafu hat geschrieben:Globale Referenzen leben für gewöhnlich länger. Man räumt üblicherweise *nicht* manuell mittels `del` ab, sondern dies geschieht automatisch nach Verlassen des jeweiligen Namensraumes. Schau dir gängige Python-Programme an, dann siehst du es.
Also, um konkret zu werden. Wir haben zwei Module a und b:
a.py:
Code: Alles auswählen
globvar = 0
Code: Alles auswählen
import a
a.globvar = 5
Irgendwann interessiert uns, ob globvar von Modul a noch existiert, und wenn ja, welchen Wert wird es haben: 0 oder 5?
Und dazu schreiben wir ein Modul c und importieren es dann auch:
c.py:
Code: Alles auswählen
import a
print(a.globvar)
@Alfons Mittelmeyer: ist das jetzt eine ernst gemeinte Frage oder willst Du mit Deinem Fettdruck nur ausdrücken, dass hier alle außer Dir keine Ahnung von Programmieren um Allgemeinen und von Python im Speziellen haben?
Nimm einfach ein paar Sachen als gegeben an:
- der Programmcode von Modulen und Funktionen existiert so lange das Programm läuft.
- in dem man keine globalen Variablen benutzt, hat man schon den ersten Schritt geschafft, dass Daten nur so lange im Speicher sind, wie sie gebraucht werden
- beherzige YAGNI
Nimm einfach ein paar Sachen als gegeben an:
- der Programmcode von Modulen und Funktionen existiert so lange das Programm läuft.
- in dem man keine globalen Variablen benutzt, hat man schon den ersten Schritt geschafft, dass Daten nur so lange im Speicher sind, wie sie gebraucht werden
- beherzige YAGNI
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
@Alfons Mittelmeyer: Du machst dir weiterhin Gedanken über Probleme, die du noch gar nicht hast. Du bist echt Beratungsresistent So langsam könnte man auf die Idee kommen, das du einfach nur Trollen willst...
Kannte ich noch gar nicht. Passt auch gut zu KISSSirius3 hat geschrieben:- beherzige YAGNI
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Sorry Sirius3, das will ich nicht ausdrücken. Aber Snafu hatte vorher auch schon einen Unsinn behauptet und BlackJack ebenso und jetzt hat snafu schon wieder Unsinn behauptet. Und das was Du jetzt schreibst, muss ich auch nicht als gegeben annehmen, denn das ist Grundwissen.Sirius3 hat geschrieben:@Alfons Mittelmeyer: ist das jetzt eine ernst gemeinte Frage oder willst Du mit Deinem Fettdruck nur ausdrücken, dass hier alle außer Dir keine Ahnung von Programmieren um Allgemeinen und von Python im Speziellen haben?
Nimm einfach ein paar Sachen als gegeben an:
- der Programmcode von Modulen und Funktionen existiert so lange das Programm läuft.
- in dem man keine globalen Variablen benutzt, hat man schon den ersten Schritt geschafft, dass Daten nur so lange im Speicher sind, wie sie gebraucht werden
- beherzige YAGNI
Aber exakt Du es nicht formuliert. So sieht es fast eher nach Hallbwissen aus.
- der Programmcode von Modulen und Funktionen existiert so lange das Programm läuft.
Also der Programmmcode befindet sich in Files .py oder .pyc und existiert daher auch länger. Beim ersten import wird der Programmcode abgearbeitet und bleibt nicht im Speicher. Im Speicher bleiben die vom Programmcode definierten globalen Strukturen, wie Klassen, Variablen und Funktionen. Wenn man in einem anderen Modul wieder einen import macht, geschieht nichts, ausser dass man dann Zugriff auf diese Funktionen Variablen usw. hat.
Im Falle von Funktionen ist der Programmcode nicht die Funktionen, sondern die Definiton der Funktionen. Nach diesen Definitionen kann man den Programmcode vergessen. Es gibt auch Module, die selber keine Funktionen etc. definieren, sondern lediglich die Werte von bereits vorhandenen globalen Strukturen ändern. Da sie selber keine globalen Definitionen enthalten, könnte man sie auch lokal in einer Funktion verpackt ablaufen lassen. Das könnte man etwa mit einer tkinter Anwendung machen. Der Vorteil wären dann lokale Variablen, lokale sonstige Namen, Defaultwerte durch lokale Variablen ausgedrückt.
Wenn man allerdings so eine Anwendung, die man importiert - beim GuiCreator waren es vor der Aufteilung in Module etwa 3000 Zeilen - jetzt in eine Funktion verpackt, indem man den Code einrückt und def buildGui(): drüberschreibt, dann muß einem bewußt sein, dass dadurch nicht nur tkinter Strukturen belegt werden, sondern man auch diese Funktion im Speicher hat. Normalerweise hätte man sie gar nicht gebraucht, sondern einfach das Modul importiert. Aber wegen dem Vorteil lokaler Namen hat man das Modul mit einer Funktion umgeben.
Und wenn man das dann importiert hat, hat man nicht dasselbe wie zuvor. Importieren alleine genügt nun nicht mehr, sondern man muss danach diese Funktion aufrufen. Und noch immer ist das Ergebnis nicht dasselbe wie zuvor. Man hat nämlich dann auch diese zusätzliche Funktion im Speicher, welche den ganzen Programmcode für eine Anwendung enthält. Wenn man ein ganzes Modul in eine Funktion verpackt hat, dann will man dann trotzdem dass nachher alles ist, wie zuvor, das heißt, dass man nach dem Aufruf dann diese Funktion durch del als Garbage markiert.
Ich verstehe nicht, warum man hier so einen Aufstand gegen del macht und falsche Behauptungen aufstellt, wie dass das automatisch von der Speicherverwaltung gelöscht würde.
Apropos Parameterübergabe: meine Rückruffunktionen hatten Dir bisher ja nicht gefallen. Schon mal einen einen Blick geworfen ins Threadthema "Gui-Anderung einer Eigenschaft in einem anderen Modul". Was sagst Du zu dieser Rückruffunktion?
Der globale Namensraum wird nicht einfach so verlassen. Daher heißt er ja auch globaler Namensraum. Ein "Verlassen" findet erst dann statt, wenn der Interpreter beendet wird (und dann gibt es auch keine Rückkehr mehr). In dem Moment wird auch `a.globvar` abgeräumt. Bis zu diesem Zeitpunkt hat man die böse, böse 5 tatsächlich dauerhaft im Speicher. Mal abgesehen davon, dass sie ohnehin im Speicher bleibt, da CPython alle kleineren Zeilen während der gesamten Interpreter-Laufzeit gecacht vorhält. `del` wird dir da also speichertechnisch rein gar nichts bringen.Alfons Mittelmeyer hat geschrieben:Also, globale Referenzen werden beseitigt, wenn man den jeweiligen Namensraum verläßt?
Und das mit dem angeblichen Unsinn überhöre ich mal...
Zuletzt geändert von snafu am Mittwoch 12. August 2015, 09:29, insgesamt 1-mal geändert.
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
:KAlfons Mittelmeyer hat geschrieben:Sorry Sirius3, das will ich nicht ausdrücken. Aber Snafu hatte vorher auch schon einen Unsinn behauptet und BlackJack ebenso und jetzt hat snafu schon wieder Unsinn behauptet. Und das was Du jetzt schreibst, muss ich auch nicht als gegeben annehmen, denn das ist Grundwissen.
@jens: Er ist der Messias, welcher in geheimen Geheimtreffen Spezialinformationen von den Python-Core-Entwicklern zum Thema `del` erhalten hat, die uns bisher bewusst vorenthalten wurden. Nicht mal in der offiziellen Python-Dokumentation sind diese Informationen zu finden. Wir sollten ihm einfach Glauben schenken. Denn Glauben ist das einzige, was uns wieder auf den rechten Programmier-Pfad bringen kann.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Also schon mal besser. Und ob alle kleineren Zeilen dauerhaft im Speicher bleiben? Der Test ergab, dass es nicht so ist. Die kleineren Zeile, sind die Zeilen, die am längsten im Speicher bleiben. Aber wenn es eng wird, kommen auch diese dran. Der Test war diese Funktion variabel hochgezählt:snafu hat geschrieben:Der globale Namensraum wird nicht verlassen. Daher heißt er ja auch globaler Namensraum. Ein "Verlassen" findet statt, wenn der Interpreter beendet wird. Und dann wird auch `a.globvar` abgeräumt. Bis zu diesem Zeitpunkt hat man die böse, böse 5 tatsächlich dauerhaft im Speicher. Mal abgesehen davon, dass sie ohnehin im Speicher bleibt, da CPython alle kleineren Zeilen während der gesamten Interpreter-Laufzeit gecacht vorhält. `del` wird dir da also speichertechnisch rein gar nichts bringen.Alfons Mittelmeyer hat geschrieben:Also, globale Referenzen werden beseitigt, wenn man den jeweiligen Namensraum verläßt?
Und das mit dem angeblichen Unsinn überhöre ich mal...
Code: Alles auswählen
def function1000000():
print "function1000000: This isn't much, normally it should be a GUI"
Mit del auch nach der ganzen Nacht mit über 15.000.000 noch kein Crash und ich konnte mit dem Computer sogar noch dabei arbeiten.
Und wie gesagt, um die kleineren Zeilen geht es mir auch nicht, sondern um größere Anwendungen. Das mit den kleinen Zeilen war nur ein Test, hoffentlich mal kapiert.
Vielleicht hast Du gemeint, dass alle kleineren Zeilen, die kein Garbage sind, dauerhaft gecasht bleiben? Garbage währen der gsamten Laufzeit dauerhaft zu cashen, wer würde denn so etwas programmieren?
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Jens Du machst Dir weiterhin Gedanken um Probleme die gar keine sind. Eine Programmierer sollte Programme schreiben und nicht tagelang darüber nachdenken, ob er jetzt del nehmen soll oder es vielleicht doch nicht braucht, da sein Computer ja 8GB Speicher hat und er ihn abends wieder ausschaltet und daher ruhig in den Speicher müllen kann. Ohne die Randbedingungen und die Endanwendungen zu kennen, kann so eine Frage nicht entschieden werden. Wenn eine Endanwendung auf einem Gerät mit 40 MB laufen würde und das Gerät monatelang nicht ausgeschaltet würde, hätte man laufend einen Crash. Der Grundsatz guter Programmierung heißt einfach, dynamisch allokierten Speicher, den man nur vorübergehend braucht, immer nach Gebrauch wieder freigeben und nicht das nächste mal wieder neu allokieren, bis kein Speicher mehr übrig ist. Du möchtest schließlich auch nicht mit einem Flugzeug abstürzen oder einen Autounfall haben, weil jemand den Speicher vollgemüllt hat.jens hat geschrieben:jens hat geschrieben:@Alfons Mittelmeyer: Du machst dir weiterhin Gedanken über Probleme, die du noch gar nicht hast. Du bist echt Beratungsresistent
Also da kannst Du mich noch soviel "beraten" wollen, wie Du es nennst. Aber so heißt mein Grundsatz, und davon weiche ich nicht ab. Und mich von etwas anderem überzeugen zu wollen. Dagegen bin ich wirklich resistent.
Wenn Du Programme anschauen willst, dann schau Dir lieber mal meinen neuen Callback im Thread "Gui-Anderung einer Eigenschaft in einem anderen Modul". Darüber können wir gerne weiter diskutieren.
Zuletzt geändert von Alfons Mittelmeyer am Mittwoch 12. August 2015, 10:14, insgesamt 2-mal geändert.