Seite 1 von 1

Decorator für Anfänger

Verfasst: Dienstag 15. September 2009, 13:17
von Humbalan
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.

Verfasst: Dienstag 15. September 2009, 13:25
von jbs

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()

Re: Decorator für Anfänger

Verfasst: Dienstag 15. September 2009, 13:27
von apollo13

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.

Verfasst: Dienstag 15. September 2009, 13:57
von Humbalan
Vielen Dank für die schnelle Antwort. Die vorgeschlagenen Lösungen sind genau das, was ich suche. :D