Hi Christopher, On 2012-12-09 15:22, Christopher Arndt wrote:
On 08.12.2012 15:18, Stefan Schwarzer wrote:
On 2012-12-08 11:35, Mike Müller wrote:
Generell würde ich `exec` nur in sehr seltenen Fällen nehmen. Es gibt fast immer eine andere, oft bessere, Lösung.
das dachte ich auch - und denke ich tendenziell immer noch. Ich war aber überrascht, als ich neulich im `collections`-Modul sah, dass für `namedtuple` eine nicht ganz kleine Klasse mit `exec` erzeugt wird
Die Verwendung von exec für "namedtuple" ist eine Geschwindigkeits-Optimierung, und die sind ja oft nicht hübsch. Es gibt dazu auch ein (rejected) Ticket im Python-Roundup mit einer kurzen Diskussion.
nach der Argumentation dort ist es ja nicht nur die Geschwindigkeit, die für die Implementierungs-Variante mit `exec` spricht. Raymond Hettinger schreibt in einem Ticket-Kommentar, "Earlier versions used other approaches and they proved unnecessarily complex and had unexpected problems." (Das heißt jetzt natürlich nicht _allgemein_, dass Lösungen mit `exec` generell besser sind. Wir hatten das ja schon so ähnlich zu `global` in diesem Thread: Dass es mitunter _keine_ gute Lösung ist, heißt nicht, dass es generell schlecht ist. Manchmal ist die Verwendung von `global` der sauberste Ansatz.)
Ich habe das mal nachgemessen und mit der Implementierung ohne "exec" verglichen. Die Definierung der neuen namedtuple-Klasse ist dadurch zwar schneller aber die Instanzierung deutlich langsamer.
Vielen Dank für den Benchmark! Ich gehe davon aus, dass viel öfter Instanzen von von `namedtuple` abgeleiteten Klassen benutzt werden als die abgeleiteten Klassen anfänglich zu erzeugen. Von daher ist der Fokus auf die _Verwendung_ der erzeugten Klasse schon vernünftig. Natürlich hängt es zudem immer vom Einzelfall ab, ob so ein Benchmark-Ergebnis für eine bestimmte Python-Anwendung relevant ist. Es kann gut sein, dass die wenigsten Anwendungen von dem Geschwindigkeitsvorteil profitieren. Viele Grüße Stefan