Wieso hast Du das geschrieben:DasIch hat geschrieben:eval() und exec leaken sehr leicht Referenzen.Dadurch lassen sich sehr leicht Memory Leaks produzierenCode: Alles auswählen
>>> eval(compile('foo = 1', '<string>', 'exec')) >>> foo 1
Wo wir übrigens bei Memory Leaks sind, folgendes als "foo.py" speichern:Code: Alles auswählen
class Foo(object): def __del__(self): print 'Collected' f = Foo()
So schnell haben wir ein Memory Leak mit exec was wir ohne gar nicht hätten.Code: Alles auswählen
λ python foo.py Collected λ python Python 2.7.10 (default, Jun 3 2015, 19:28:03) [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.49)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import gc >>> for _ in range(10): ... execfile('foo.py', {}) ... print gc.collect(), len(gc.garbage) ... 9 1 9 2 9 3 9 4 9 5 9 6 9 7 9 8 9 9 9 10
Dazu kommen dann noch Probleme bei statischer Analyse, Debugging und Dokumentation die das Leben spannender machen. Die Kombination von Code der Introspektion betreibt und eval/exec dürfte auch zu Probleme führen. Von Performance dürfte man sich auch verabschieden können.
Wie kommt man eigentlich auf die Idee dass der Source Code in Form von Strings weniger Speicher verbraucht, als der equivalente Code in Form eines importiertem Moduls?
Code: Alles auswählen
# Hier legst Du mit dem zweiten Parameter {} neue Globals an und machst die alten unerreichbar. Und genau das ist das Problem.
execfile('foo.py', {})
# richtig ist:
execfile('foo.py')