hi!
ich habe letztens irgendwo (es war bei den decoratoren) ein @ gelesen, dessen bedeutung ich nicht verstanden habe.
nun dachte ich mir, das schaue ich mir mal im wiki an, aber: unter "@" lässt sich nichts finden!
könnte das ins wiki gestellt werden?
anfängerfrage: das @
http://www.cs.unm.edu/~dlchao/flake/doom/
-
- User
- Beiträge: 1790
- Registriert: Donnerstag 28. Oktober 2004, 16:33
- Wohnort: Graz, Steiermark - Österreich
- Kontaktdaten:
Das @ gibt es nur für Dekoratoren. Und die Fausregel ist:
ist das gleiche wie
und folgedem ist auch
das gleiche wie
Und mehr gibts dazu nicht zu sagen. Wenn du das noch nie gebraucht hast wird dich auch das "@" nicht interessieren.
Code: Alles auswählen
@foo
def bar():
pass
Code: Alles auswählen
def bar():
pass
bar = foo(bar)
Code: Alles auswählen
@foo()
def bar():
pass
Code: Alles auswählen
def bar():
pass
bar = foo()(bar)
TUFKAB – the user formerly known as blackbird
Na ja, hast recht, wobei solch eine Syntax für Classmethods schon ganz nützlich ist ...
Gruß,
Christian
Gruß,
Christian
aber was bringt ein decorator?
ich habe zwar http://soiland.no/software/decorator gelesen, konnte dem aber keine informationen entnehmen, stehe irgendwie da auf dem schlacuh.
ich habe zwar http://soiland.no/software/decorator gelesen, konnte dem aber keine informationen entnehmen, stehe irgendwie da auf dem schlacuh.
http://www.cs.unm.edu/~dlchao/flake/doom/
Wie gesagt, du kannst eine Funktion auf die Funktion anwenden. Zum beispiel sinnvoll bei sowas:aber was bringt ein decorator?
Code: Alles auswählen
class abc:
@property
def enabled(self):
return True
b = abc()
b.enabled # b.enabled, nicht b.enabled()
Sinnvoll sind Dekoratoren zb, um funktionen zu "wrappen".
Gegeben sei zB die Situation, dass eine Art Zugriffsgenehmigung auf Funktionsebene gebraucht ist (hat man häufig in webframeworks).
Man hat viele recht einfache Funktionen, die vom Endbenutzer eines Frameworks geschrieben werden sollen:
Jetzt möchte der Entwickler der Bibliothek diesen Benutzern recht einfach ermöglichen, Sicherheitschecks zu machen. Er macht also einen Dekorator, der in etwa so aussieht:
Es ist eine Funktion, der einen Wrapper für die übergebene Funktion erzeugt.
Diese Funktion kann nun als Dekorator genutzt werden:
Das sorgt dafür, dass an den Namen "pageB" nicht mehr die eigentliche funktion pageB gebunden ist, sondern das resultat von permissionRequired(pageB), welches "im prinzip" die funktion B mit einem sicherheitscheck ist.
Es gibt noch einen ganzen Haufen anderer Verwendungen für Dekoratoren, aber diese ist mir bis jetzt am häufigsten untergekommen.
Gegeben sei zB die Situation, dass eine Art Zugriffsgenehmigung auf Funktionsebene gebraucht ist (hat man häufig in webframeworks).
Man hat viele recht einfache Funktionen, die vom Endbenutzer eines Frameworks geschrieben werden sollen:
Code: Alles auswählen
def pageA(request):
print "Hello world!"
def pageB(request):
print "Hello Again!"
Code: Alles auswählen
def permissionRequired(unsafeFunction):
def wrapper(*args, **kwargs):
if user_has_permission:
unsafeFunction(*args, **kwargs)
else:
print "Breakin' the Law!"
return wrapper
Diese Funktion kann nun als Dekorator genutzt werden:
Code: Alles auswählen
@permissionRequired
def pageB(request):
print "Hello Again!"
Es gibt noch einen ganzen Haufen anderer Verwendungen für Dekoratoren, aber diese ist mir bis jetzt am häufigsten untergekommen.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Ein Dekorator ist nur "syntactic sugar", der stattmurph hat geschrieben:aber was bringt ein decorator?
Code: Alles auswählen
def bar():
pass
bar = foo(bar)
Code: Alles auswählen
@foo
def bar():
pass
an sich also ganz gut, wenn man bei jedem aufruf einer funktion bestimmte sachen testen möchte etc.
in diesem fall wird beim aufruf einer beliebigen funktion, die nach dem dekorator genannt wird, erst der dekorator aufgerufen, dann überprüft, ob der user die rechte hat, und dann vom wrapper die gewünschte funktion ausgeführt...aber die funktion wird doch automatisch ausgeführt, wenn man sie für einen aufruf benutzt!?! oder wenn man dieses nicht tut, dann sind aber alle argumente in einem tuple, d.h., wenn das ganze auf etwas noch anderem basiert, muss man erstmal den kladderadatsch aus dem tuple holen...oder?
Code: Alles auswählen
def permissionRequired(unsafeFunction):
def wrapper(*args, **kwargs):
if user_has_permission:
unsafeFunction(*args, **kwargs)
else:
print "Breakin' the Law!"
return wrapper
http://www.cs.unm.edu/~dlchao/flake/doom/
kennt wer ein gutes tutorial dazu?
habe grade genau das richtige für einen wrapper, muss aber bisschen daran rumschrauben.
Danke im Voraus!
habe grade genau das richtige für einen wrapper, muss aber bisschen daran rumschrauben.
Danke im Voraus!
http://www.cs.unm.edu/~dlchao/flake/doom/
thx
http://www.cs.unm.edu/~dlchao/flake/doom/
jein, das stimmt so nicht ganz. es wird nicht "erst" der dekorator, sondern _nur_ die funktion, die der dekorator zurückgibt, aufgerufen.in diesem fall wird beim aufruf einer beliebigen funktion, die nach dem dekorator genannt wird, erst der dekorator aufgerufen,
man stelle sich vor, man riefe diesen dekorator von hand auf
Code: Alles auswählen
def innocentFunction(a, b, c):
print a, b, c
# punkt 1
innocentFunction= permissionRequired(innocentFunction)
# punkt 2
Allerdings wird dieser name nach punkt 1 neu gebunden, und zwar an das resultat der funktion permissionRequired, die auch eine funktion zurückgibt.
nein, weil diese funktion ja nicht mehr mit diesem namen verknüpft ist.dann überprüft, ob der user die rechte hat, und dann vom wrapper die gewünschte funktion ausgeführt...aber die funktion wird doch automatisch ausgeführt, wenn man sie für einen aufruf benutzt!?!
der name "innocentFunction" ist an den wrapper gebunden, den "permissionRequired" zurückgegeben hat, das ganze ding ist in jeder hinsicht einfach nur eine funktion.
ich verstehe nicht ganz, was du hier meinst.oder wenn man dieses nicht tut, dann sind aber alle argumente in einem tuple, d.h., wenn das ganze auf etwas noch anderem basiert, muss man erstmal den kladderadatsch aus dem tuple holen...oder?
edit: ich bastele gerade im Pythonwiki an einer Einführung. Anregungen oder Korrekturen sind erwünscht