Decorator für Anfänger

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Humbalan
User
Beiträge: 59
Registriert: Mittwoch 2. September 2009, 15:11

Hallo,

erst seit kurzem beschäftige ich mich mit Decorators und habe bei einem Testprogramm ein Verhalten entdeckt, dass ich mir nicht erklären kann. Im www habe ich dazu leider nichts gefunden.

Das ursprüngliche Programm:

Code: Alles auswählen

def afunc():
    print 'afunc(): inside afunc'

def main():
    print '**** main() ****'
    print 'main(): calling afunc'
    afunc()
    print 'main(): returning from afunc'

main()
Das Verhalten ist wie erwartet:
  • **** main() ****
    main(): calling afunc
    afunc(): inside afunc
    main(): returning from afunc
So weit so gut.
Jetzt erfinde ich einen decorator mydec() und schreibe je einen Aufruf vor die Funktionen afunc() und main():

Code: Alles auswählen

def mydec(inFunc):
    print 'mydec(): calling', inFunc.__name__
    inFunc()
    print 'mydec(): returning from', inFunc.__name__
    return inFunc

@mydec
def afunc():
    print 'afunc(): inside afunc'

@mydec
def main():
    print '**** main() ****'
    print 'main(): calling afunc'
    afunc()
    print 'main(): returning from afunc'

main()
und erwarte als Output
  • mydec(): calling main
    **** main() ****
    main(): calling afunc
    mydec(): calling afunc
    afunc(): inside afunc
    mydec(): returning from afunc
    main(): returning from afunc
    mydec(): returning from main
bekomme aber
  • mydec(): calling afunc
    afunc(): inside afunc
    mydec(): returning from afunc
    mydec(): calling main
    **** main() ****
    main(): calling afunc
    afunc(): inside afunc
    main(): returning from afunc
    mydec(): returning from main
    **** main() ****
    main(): calling afunc
    afunc(): inside afunc
    main(): returning from afunc
Was mache ich falsch?
Danke für Eure Hilfe.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Code: Alles auswählen

@dec
def a(): pass
#ist
a = dec(a)
[/code]


was du möchtest ist sicherlich:

Code: Alles auswählen

def decorator(func):
    def wrapper(*args, **kwargs):
        print 'before call'
        ret = func(*args, **kwargs)
        print 'after call'
        return ret
    return wrapper

@decorator
def function():
    print 'hallo'
    
function()
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Code: Alles auswählen

def mydec(inFunc):
  def wrap(*args, **kwargs)
    print 'mydec(): calling', inFunc.__name__
    x = inFunc(*args, **kwargs)
    print 'mydec(): returning from', inFunc.__name__
    return x
  return wrap

@mydec
def afunc():
    print 'afunc(): inside afunc'

@mydec
def main():
    print '**** main() ****'
    print 'main(): calling afunc'
    afunc()
    print 'main(): returning from afunc'

main()
So sollte es gehen (ungetestet). Dein Problem ist ansich, dass der Decorator beim ausführen der Datei und nicht der Funktion aufgerufen wird, deshalb die wrap Funktion.
Benutzeravatar
Humbalan
User
Beiträge: 59
Registriert: Mittwoch 2. September 2009, 15:11

Vielen Dank für die schnelle Antwort. Die vorgeschlagenen Lösungen sind genau das, was ich suche. :D
Antworten