Seite 1 von 1
Referenz auf die aktuelle Funktion
Verfasst: Dienstag 2. Juni 2009, 10:55
von filchos
Hallo,
folgendes Szenario:
Ein Decorator fügt Informationen zu einer Funktion hinzu:
Code: Alles auswählen
def internal(function):
function.internal = True
return function
Gibt es eine einfache Möglichkeit, innerhalb der Funkion das Attribut internal auszulesen, ohne den Funktionsnamen selbst zu benutzen?
Also statt
Code: Alles auswählen
@internal
def example():
internal = getattr(example, 'internal')
# do something
lieber so eine Art
Code: Alles auswählen
@internal
def example():
internal = getattr(__THIS_IS_A_REFERENCE_TO_THE_CURRENT_FUNCTION__, 'internal')
# do something
?
Schöne Grüße,
Olaf
Verfasst: Dienstag 2. Juni 2009, 11:04
von BlackJack
@filchos: Nein, gibt's nicht.
Verfasst: Dienstag 2. Juni 2009, 11:05
von filchos
Hallo BlackJack,
danke für die Antwort, dann muss ich auch nicht weitersuchen.
Grüße,
Olaf
Verfasst: Dienstag 2. Juni 2009, 11:31
von sma
Dies ist ein Hack, der nur mit CPython und globalen Funktionen funktioniert...
Code: Alles auswählen
def internalize(f): f.internal = True; return f
def am_i_internal():
import sys; f = sys._getframe(1)
return getattr(f.f_globals[f.f_code.co_name], 'internal', False)
def foo():
if am_i_internal():
return 42
return 2
print foo()
print internalize(foo)()
Sauber ist IMHO der Einsatz von dynamischen aka fluid Variablen:
Code: Alles auswählen
from threading import local
current = local()
def internalize(f):
def inner(*args, **kwargs):
oldf = getattr(current, "f", None); current.f = f
try:
return f(*args, **kwargs)
finally:
current.f = oldf
f.internal = True
return inner
def am_i_internal():
return getattr(getattr(current, "f", None), 'internal', False)
def foo():
if am_i_internal():
return 42
return 2
print foo()
print internalize(foo)()
Stefan
Verfasst: Dienstag 2. Juni 2009, 18:07
von filchos
Hallo Stefan,
danke für Deine Antwort. Sie ist für mich allerdings hauptsächlich zum Lernen interessant. Für eine Umsetzung, für die ich auch andere Möglichkeiten habe, ist sie mir zu komplex.
Grüße,
Olaf
Verfasst: Dienstag 2. Juni 2009, 18:59
von birkenfeld
Hab ich vor kurzem mal für python-ideas geschrieben:
Code: Alles auswählen
def selffunc(func):
@wraps(func)
def newfunc(*args, **kwds):
return func(func, *args, **kwds)
return newfunc
@selffunc
def foo(func, a):
func.cache = a
Verfasst: Mittwoch 3. Juni 2009, 06:56
von filchos
Hallo birkenfeld,
was macht die Funktion „wraps“?
Grüße,
Olaf
Verfasst: Mittwoch 3. Juni 2009, 07:00
von Trundle
Die kommt aus dem [mod]functools[/mod]-Modul und setzt bei `newfunc` Attribute wie `__name__`, `__module__` und `__doc__`, damit `newfunc` eben so aussieht wie `func`.
Verfasst: Mittwoch 3. Juni 2009, 08:04
von birkenfeld
Tatsächlich, da hab ich den Import vergessen.