Was muss ich in Python 3 importieren, damit es print kennt?

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.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das ist Unsinn :roll:

Schau dir mal https://de.wikipedia.org/wiki/Garbage_Collection an!

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Alfons Mittelmeyer hat geschrieben:Euren skurrilen Ansichten
Euch gleich wieder rauszuwerfen
Was soll denn dieser Unsinn wieder
Es ist die Pflicht jedes professionellen Programmierers
Für Pipifax Desktop Anwendungen freilich, braucht man so etwas nicht
Und Ihr wollt mir vorschreiben, dass hier schlampig programmieren Pflicht ist und korrekt programmieren verboten?
Geh bitte. Du bist hier anscheinend falsch. ><((((*>
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Also beachtet bitte die Regel: del darf man für Einträge in dictionaries nehmen und für Einträge in Listen, sonst aber nicht.
Die richtige Art globale einzelne Definitionen zu löschen - also was man nicht in globale Listen oder globale Dictionaries eingetragen hat - ist daher diese:

Code: Alles auswählen

def myfunction(): pass

del globals()['myfunction']
globals() ist allerdings nur der Namensraum für die Hauptanwendung.
Zuletzt geändert von Alfons Mittelmeyer am Sonntag 16. August 2015, 12:08, insgesamt 1-mal geändert.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Alfons Mittelmeyer hat geschrieben:Jede Sprache verwaltet den Speicher automatisch. So werden lokale Variablen wieder gelöscht. Globale Variablen werden aber nicht gelöscht.
Du vermischt da einige Konzepte. In kompelierten Sprachen werden globale Variablen üblicherweise im `.data`-Segement abgelegt:

Code: Alles auswählen

int x = 3;
static int y = 5;

void main(void) {}

Code: Alles auswählen

╭─dav1d@doom  /tmp  
╰─$ gcc global.c -o global 
╭─dav1d@doom  /tmp  
╰─$ objdump -t global

global:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000              init.c
0000000000000000 l    df *ABS*	0000000000000000              crtstuff.c
0000000000401928 l     O .jcr	0000000000000000              __JCR_LIST__
0000000000401930 l     O .tm_clone_table	0000000000000000              __TMC_LIST__
0000000000400490 l     F .text	0000000000000000              deregister_tm_clones
00000000004004d0 l     F .text	0000000000000000              register_tm_clones
0000000000400510 l     F .text	0000000000000000              __do_global_dtors_aux
0000000000401940 l     O .bss	0000000000000001              completed.6938
0000000000401930 l     O .fini_array	0000000000000000              __do_global_dtors_aux_fini_array_entry
0000000000400530 l     F .text	0000000000000000              frame_dummy
0000000000401938 l     O .init_array	0000000000000000              __frame_dummy_init_array_entry
0000000000000000 l    df *ABS*	0000000000000000              global.c
0000000000401924 l     O .data	0000000000000004              y
0000000000000000 l    df *ABS*	0000000000000000              crtstuff.c
00000000004006d8 l     O .eh_frame	0000000000000000              __FRAME_END__
0000000000401928 l     O .jcr	0000000000000000              __JCR_END__
0000000000401918 l     O .data	0000000000000000              .hidden __dso_handle
0000000000401930 l     O .tm_clone_table	0000000000000000              .hidden __TMC_END__
0000000000401710 l     O .dynamic	00000000000001d0              .hidden _DYNAMIC
0000000000401938 l       .init_array	0000000000000000              .hidden __init_array_start
0000000000401940 l       .init_array	0000000000000000              .hidden __init_array_end
00000000004018e8 l     O .got.plt	0000000000000028              .hidden _GLOBAL_OFFSET_TABLE_
00000000004005d0 g     F .text	0000000000000002              __libc_csu_fini
0000000000400460 g     F .text	000000000000002a              _start
0000000000400560 g     F .text	0000000000000065              __libc_csu_init
0000000000400556 g     F .text	0000000000000007              main
0000000000401910  w      .data	0000000000000000              data_start
00000000004005e0 g     O .rodata	0000000000000004              _IO_stdin_used
0000000000000000       F *UND*	0000000000000000              __libc_start_main
0000000000401910 g       .data	0000000000000000              __data_start
0000000000000000  w      *UND*	0000000000000000              __gmon_start__
0000000000400408 g     F .init	0000000000000000              _init
00000000004005d4 g     F .fini	0000000000000000              _fini
0000000000000000  w      *UND*	0000000000000000              _ITM_deregisterTMCloneTable
0000000000000000  w      *UND*	0000000000000000              _ITM_registerTMCloneTable
0000000000000000  w      *UND*	0000000000000000              _Jv_RegisterClasses
0000000000401920 g     O .data	0000000000000004              x
0000000000401940 g       *ABS*	0000000000000000              _edata
0000000000401940 g       *ABS*	0000000000000000              __bss_start
0000000000401941 g       *ABS*	0000000000000000              _end
Darin findet man diese 2 Einträge:

Code: Alles auswählen

0000000000401924 l     O .data	0000000000000004              y
0000000000401920 g     O .data	0000000000000004              x
Also globale Variablen haben schonmal absolut nichts mit Speicherverwaltung zu tun (PS: ob die globale Variable mit static deklariert wurde oder nicht sieht man am `l` oder `g`).

Nun zu lokalen Variablen, diese werden auf einem Stack-Segement abgelegt, welches von dem Stack wieder "entfernt" wird sobald die der Scope verlassen wird.

Nun zur eigenltichen Speicherverwaltung, dem Heap, das "Gegenstück" zum Stack, welcher nicht automatisch wächst und Speicher nicht "automatisch" freigegeben werden wie beim Stack. Speicher der im Heap reserviert wird bleibt bestehen bis er wieder freigegeben wird. Man kann z.B. Speicher via `malloc` reservieren und wieder mit `free` freigeben, dann gibt es noch die Variante über einen Garbage Collector (von Jens angesprochen) Speicher zu reservieren, der GC kümmert sich darum dass Speicher wieder freigegeben wird sobald er nicht mehr benutzt wird (vereinfacht: er scannt den Speicherbereich nach Referenzen/Pointern, wenn er etwas findet dass in einen reservierten Bereich zeigt, wird der Speicher noch gebraucht und nicht freigegeben).

Python benutzt einen solchen Garbage Collector (gibts übrigens auch für C/C++, z.B. libgc). Also alles was du tust ist im Grunde dem Garbage Collector die Arbeit zu erschweren und machst es teilweise sogar schlimmer (z.B. das copy). Es kann durchaus Situationen geben in denen `del` Sinn macht, allerdings für jemanden wie dich, der nicht wirklich versteht was los ist mit Memory Management sollte die Finger davon lassen.

Fazit: Du verrennst dich da in Sinnlosem, wenn du wirklich ein low memory profile brauchst (also wirklich wirklich wirklich low), dann nimm nicht Python. Aber denke jetzt nicht, wusste ich doch gleich Python taugt nix, Garbage Collectoren sind scheiße. Python läuft ohne Probleme auf Micro-Controllern und ein guter Garbage Collector kann durchaus mal schneller und effizienter sein als manuelles Memory Management von einem der keine Ahnung hat wies geht ;).

PS: Wenn du versuchst Module zu entladen, das geht sowieso nicht wirklich: http://bugs.python.org/issue9072.
the more they change the more they stay the same
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Dav1d hat geschrieben:
Alfons Mittelmeyer hat geschrieben:Jede Sprache verwaltet den Speicher automatisch. So werden lokale Variablen wieder gelöscht. Globale Variablen werden aber nicht gelöscht.
Du vermischt da einige Konzepte. In kompelierten Sprachen werden globale Variablen üblicherweise im `.data`-Segement abgelegt:
Du vermischt da einige Konzepte. Statische globale Variablen werden im '.data' - Segment abgelegt. Bei dynamisch allokiertem Speicher werden nur die Pointer also die Verweise auf den Speicher im '.data' Segment abgelegt. Und der Speicher wird dann aus dem Heap allokiert, etwa:

Code: Alles auswählen

# hier wird ein globaler Pointer myVar definiert, der im '.data' Segment als Verweis auf bisher nichts Brauchbares abgelegt wird.
# außerdem wird er als Pointer auf eine Klasse definiert, sodass er nur auf diese Klasse anwendbar ist
# (natürlich gibt es auch Möglichkeiten Pointer für beliebige Klassen zu verwenden mit Datentyp void und dann type casts)
MyClass * myVar = Null

# und hier findet dann die eigentliche Zuweisung statt, in der dann Speicher dynamisch allokiert wird
myVar = new MyClass(par1,par2,par3)

# und wenn der Speicher nicht freigegeben wird, bleibt dieser erhalten. Genauso ist es in Python. Zum Freigeben existiert der Befehl delete und in Python heißt er del
# Python hat allerdings eine Speicherverwaltung, die sich um Vieles kümmert, sodass man das del nicht explizit braucht, weil es in einigen Befehlen schon enthalten ist.
# wenn man in C++ nun das schreiben würde, wäre es verkehrt:
myVar = new MyClass(otherpar1,otherpar2,otherpar3)

# denn dadurch verursacht man ein Memory Leak, weil man jetzt neuen Speicher allokiert hat, ohne den alten freizugeben
# richtig daher:
delete myVar
myVar = new MyClass(otherpar1,otherpar2,otherpar3)

# In Python ist hier ein del völlig unnötig, wel das del bereits in der Zuweisung mit enthalten ist, genauso, wie etwa auch bei pop()
# Und wer hier del benutzt betreibt Mikroprogrammierung und hat von der Speicherverwaltung von Python nichts verstanden
Dav1d hat geschrieben:Also globale Variablen haben schonmal absolut nichts mit Speicherverwaltung zu tun (PS: ob die globale Variable mit static deklariert wurde oder nicht sieht man am `l` oder `g`).
Wie wir gesehen hatten, haben globale Pointer mit dynamisch allokiertem Speicher sehr wohl etwas mit Speicherverwaltung zu tun. Bei statischen Variablen bleibt allerdings der Speicher stets gleich und muss man sich nicht darum kümmern. Der Vorteil der Speicherverwaltung von Python ist, dass man sich normalerweise durch das in der Zuweisung und der pop-Funktion bereits enthaltene del, so ziemlich gar nicht um die Speicherverwaltung zu kümmern braucht. Stimmt natürlich nicht ganz, denn wer Daten in Listen und dergleichen speichert, da immer mehr hineinmüllt und sich nicht darum kümmert, dass etwas nur kurzzeitig gebraucht wurde, und glaubt, dass die Speicherverwaltung automatisch seinen Saustall aufräumt, der liegt verkehrt.
Dav1d hat geschrieben:Nun zur eigenltichen Speicherverwaltung, dem Heap, das "Gegenstück" zum Stack, welcher nicht automatisch wächst und Speicher nicht "automatisch" freigegeben werden wie beim Stack. Speicher der im Heap reserviert wird bleibt bestehen bis er wieder freigegeben wird. Man kann z.B. Speicher via `malloc` reservieren und wieder mit `free` freigeben, dann gibt es noch die Variante über einen Garbage Collector (von Jens angesprochen) Speicher zu reservieren, der GC kümmert sich darum dass Speicher wieder freigegeben wird sobald er nicht mehr benutzt wird (vereinfacht: er scannt den Speicherbereich nach Referenzen/Pointern, wenn er etwas findet dass in einen reservierten Bereich zeigt, wird der Speicher noch gebraucht und nicht freigegeben).


Daraus besonders dieser Teil:
der GC kümmert sich darum dass Speicher wieder freigegeben wird sobald er nicht mehr benutzt wird[/b] (vereinfacht: er scannt den Speicherbereich nach Referenzen/Pointern, wenn er etwas findet dass in einen reservierten Bereich zeigt, wird der Speicher noch gebraucht und nicht freigegeben).
Ob der Speicher noch benutzt werden soll, weiss der gc nicht. Er weiss nur ob der Referenzzähler Null ist oder nicht - bzw. ob die Referenz noch beinen reservierten Speicherbereich zeigt. Also, ob etwas noch gebraucht wird, weiß der gc nicht und wenn jemand Objekte, die er nicht mehr braucht, nicht aufräumen will sondern einfach weiter ansammelt, dann wird eben der Speicher vollgemüllt, bis Python bedendet wird oder bis es einen Crash gibt. Und bei lang laufenden Programmen mit großen Datenbeständen, kommt es eben dann zu Crashs.

Während lokale Variablen in Funktionen selber wieder beseitigt werden, werden globale Variablen nicht von selber aufgeräumt, sondern die Daten bleiben erhalten, bis man sie löscht. Warum man bei Einträgen in Listen und Directories dazu del nehmen darf, bei einzelnen Variablen dagegen nicht, bleibt ein Rätsel.
Dav1d hat geschrieben:Python benutzt einen solchen Garbage Collector (gibts übrigens auch für C/C++, z.B. libgc). Also alles was du tust ist im Grunde dem Garbage Collector die Arbeit zu erschweren und machst es teilweise sogar schlimmer (z.B. das copy). Es kann durchaus Situationen geben in denen `del` Sinn macht, allerdings für jemanden wie dich, der nicht wirklich versteht was los ist mit Memory Management sollte die Finger davon lassen.
Anscheinend bin ich der einzige hier der etwas vom Memory Management versteht. Und solche wie Du sollten da einfach besser still sein. Vielleicht viel Bücher gelesen, verstanden aber offentlich nichts.
Dav1d hat geschrieben:Fazit: Du verrennst dich da in Sinnlosem, wenn du wirklich ein low memory profile brauchst (also wirklich wirklich wirklich low), dann nimm nicht Python. Aber denke jetzt nicht, wusste ich doch gleich Python taugt nix, Garbage Collectoren sind scheiße. Python läuft ohne Probleme auf Micro-Controllern und ein guter Garbage Collector kann durchaus mal schneller und effizienter sein als manuelles Memory Management von einem der keine Ahnung hat wies geht ;).

PS: Wenn du versuchst Module zu entladen, das geht sowieso nicht wirklich: http://bugs.python.org/issue9072.
Ich brauche kein low memory profile aber ein grow and grow and grow memory profile ebensowenig. Und Python ist optimal geeignet, hervorragend. Ein guter Garbage Collector kann keinen Saustall aufräumen, weil jemand den Speicher vollmüllt. Ein manuelles Memory Management brauche ich nicht. Denn ich habe die destroy() Funktion geschrieben, die den Speicher leer räumt. Und wer überhaupt keine Ahnung hat, bist Du. Sonst hättest Du gemerkt, dass ich darüber gar nicht mehr dikutieren brauche, weil ich die Funktion habe, die automatisch nach Ablaufen eines Scripts, den vom Script verwendeten Speicher wieder löscht. Und um Module ging es auch nicht, sondern um Scripts.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Alfons Mittelmeyer hat geschrieben:Du vermischt da einige Konzepte. Statische globale Variablen werden im '.data' - Segment abgelegt. Bei dynamisch allokiertem Speicher werden nur die Pointer also die Verweise auf den Speicher im '.data' Segment abgelegt. Und der Speicher wird dann aus dem Heap allokiert, etwa:
Ich habe allgemein von globalen Variablen gesprochen, nicht was man diesen zuweist.
Alfons Mittelmeyer hat geschrieben:Wie wir gesehen hatten, haben globale Pointer mit dynamisch allokiertem Speicher sehr wohl etwas mit Speicherverwaltung zu tun. Bei statischen Variablen bleibt allerdings der Speicher stets gleich und muss man sich nicht darum kümmern. Der Vorteil der Speicherverwaltung von Python ist, dass man sich normalerweise durch das in der Zuweisung und der pop-Funktion bereits enthaltene del, so ziemlich gar nicht um die Speicherverwaltung zu kümmern braucht. Stimmt natürlich nicht ganz, denn wer Daten in Listen und dergleichen speichert, da immer mehr hineinmüllt und sich nicht darum kümmert, dass etwas nur kurzzeitig gebraucht wurde, und glaubt, dass die Speicherverwaltung automatisch seinen Saustall aufräumt, der liegt verkehrt.
Ich denke du weißt nicht was das `static` Keyword in C bedeutet, besonders im Zusammenhang mit globalen Variablen.

Natürlich kann man Referenzen auf jedes Objekt in einer Liste speichern, aber wer macht das schon .. du behälst ganz automatisch nur die Referenzen die du später noch brauchst, del ist da überflüssig.
Alfons Mittelmeyer hat geschrieben:Daraus besonders dieser Teil:
der GC kümmert sich darum dass Speicher wieder freigegeben wird sobald er nicht mehr benutzt wird[/b] (vereinfacht: er scannt den Speicherbereich nach Referenzen/Pointern, wenn er etwas findet dass in einen reservierten Bereich zeigt, wird der Speicher noch gebraucht und nicht freigegeben).
Ob der Speicher noch benutzt werden soll, weiss der gc nicht. Er weiss nur ob der Referenzzähler Null ist oder nicht - bzw. ob die Referenz noch beinen reservierten Speicherbereich zeigt. Also, ob etwas noch gebraucht wird, weiß der gc nicht und wenn jemand Objekte, die er nicht mehr braucht, nicht aufräumen will sondern einfach weiter ansammelt, dann wird eben der Speicher vollgemüllt, bis Python bedendet wird oder bis es einen Crash gibt. Und bei lang laufenden Programmen mit großen Datenbeständen, kommt es eben dann zu Crashs.
Ein GC basiert nicht (zwingend) auf Reference Counts. Zu dem Problem das du beschreiben willst, du programmierst schlecht wenn du Referenzen auf unbenutzte Objekte behälst. Deine "destroy" oder sonstwas Funktion bringt dir auch nichts, wenn noch ein anderes Objekt eine Referenz behält, also schwachsinn.
Alfons Mittelmeyer hat geschrieben:Während lokale Variablen in Funktionen selber wieder beseitigt werden, werden globale Variablen nicht von selber aufgeräumt, sondern die Daten bleiben erhalten, bis man sie löscht. Warum man bei Einträgen in Listen und Directories dazu del nehmen darf, bei einzelnen Variablen dagegen nicht, bleibt ein Rätsel.
Weil `del` bei Dictionaries "magisch" ist und bedeutet, "entferne diesen Key aus dem Dictionary".
Alfons Mittelmeyer hat geschrieben:Ich brauche kein low memory profile aber ein grow and grow and grow memory profile ebensowenig. Und Python ist optimal geeignet, hervorragend. Ein guter Garbage Collector kann keinen Saustall aufräumen, weil jemand den Speicher vollmüllt. Ein manuelles Memory Management brauche ich nicht. Denn ich habe die destroy() Funktion geschrieben, die den Speicher leer räumt. Und wer überhaupt keine Ahnung hat, bist Du. Sonst hättest Du gemerkt, dass ich darüber gar nicht mehr dikutieren brauche, weil ich die Funktion habe, die automatisch nach Ablaufen eines Scripts, den vom Script verwendeten Speicher wieder löscht. Und um Module ging es auch nicht, sondern um Scripts.
Nach beendigung eines Scripts/Programms wird der Speicher vom Betriebssystem sowieso wieder freigegeben. Was du als "Skript" bezeichnest ist eine Krankheit, ein Missbrauch des Modulsystems von Python, der eine oder andere Python Enthusiast wird sich bei solch einem Code im Grab umdrehen.
the more they change the more they stay the same
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

><((((*>

Selbst wenn es aus tatsächlichem Unwissen und Nicht-Wahrhaben-Wollen begründet ist, so hat trotzdem ein wiederholtes Eröffnen von Threads nach Sperrung, die immer wieder auf das selbe Thema hinauslaufen und sich X-mal im Kreis drehen, ganz starke Züge von Trolling. Besonders hier ist es IMHO offensichtlich, dass die Sache mit `print()` ein billiger Vorwand war.

EDIT: Und durch das massive Verbreiten von Falschinformationen leidet zudem die Qualität des Forums. Ich persönlich denke ja langsam, dass hier durchaus andere Maßnahmen eingeleitet werden könnten. Oder sollen wir demnächst 10 gesperrte Threads auf der ersten Seite von Allgemeine Fragen haben? Aber über diese Schritte sollte natürlich gemeinschaftlich entschieden werden.
BlackJack

Ich denke auch das dieses Thema schon wieder um die gleiche falsche Annahme geht und sich die Argumente wiederholen. Darum ist hier jetzt Schluss.

Und falls das demnächst in einem neuen Thema wieder losgeht, sollte man definitiv über andere Massnahmen nachdenken. Was sehr traurig ist, denn so etwas war hier AFAIR noch nie nötig, jedenfalls nicht bei Benutzern die nicht reine Spammer waren.
Gesperrt