Frame-Objekte

Frame-Objekte in Python entsprechen Zuständen der virtuellen Maschine in Python. Sie beinhalten z.B. Informationen über den aktuell ausgeführten Code (als Code-Objekt), dessen lokale und globale Variablen als Dictionaries und - vielleicht am wichtigsten - einen Referenz auf den vorhergehenden Frame. Normalerweise werden Frame-Objekte in Python nur zum Erzeugen von Tracebacks beim Exception-Handling gebraucht. Es gibt aber daneben auch eine Funktion im Modul sys, die das dem aktuellen Frame entsprechende Objekt zurückliefert: _getframe. Der Name, beginnend mit einem Unterstrich, deutet es schon an und die Dokumentation macht es ausdrücklich:

This function should be used for internal and specialized purposes only.

Man kann damit also eine ganze Menge Unsinn anstellen. Aufgrund Implementation von Funktionen in Python ist es nicht möglich deren lokale Variablen zu manipulieren für viele Zwecke ist aber schon das Lesen ausreichend, um Verwirrung zu stiften:

>>> import sys
>>> def get_x():
...   f = sys._getframe(1)
...   return f.f_locals["x"]
...
>>> def f(x):
...   return get_x()
...
>>> f("Hello")
'Hello'

Das würde es z.B. möglich machen so etwas wie Rubys Blöcke in Python zu implementieren. Aber auch für billige Metaprogrammierung lassen sich Frames missbrauchen, denn bei Klassen sind die lokalen Variablen (d.h. die Attribute der Klasse) veränderbar:

>>> def abc():
...   f = sys._getframe(1)
...   l = f.f_locals
...   l["a"] = 1
...   l["b"] = 2
...   l["c"] = 3
...
>>> class Test(object):
...   abc()
...
>>> T.a, T.b, T.c
(1, 2, 3)

An einer Stelle habe ich _getframe auch schon einmal benutzt, um in einer Funktion eine Rekursion, die durch Verhalten in fremden Code auftauchen konnte. Sich andere lustige oder nützliche Verwendungen einfallen zu lassen, sei dem geneigten Leser zur Übung überlassen.