2017-09-02 1 views
0

Je reçois le principe de base des décorateurs Python et j'aime la syntaxe. Cependant, ils semblent un peu limités sur ce que vous pouvez faire.Décorateur Python pour des fonctions multiples comme arguments?

Existe-t-il un moyen élégant de gérer plusieurs fonctions comme des arguments comme ci-dessous?

def parent_fn(child_fn1, child_fn2): 
    def wrapper(): 
     print('stuff is happening here') 
     child_fn1() 
     print('other stuff is happening here') 
     child_fn2() 
    return wrapper 

@parent_fn 
def decorated(): 
    print('child_fn1 stuff here') 

decorated() 

Où pourrais-je mettre le code child_fn2? Les quelques idées que j'ai essayées semblent enlever de la simplicité et de l'élégance du décorateur.

Répondre

2

Vous pouvez le faire:

import functools 

def sequence_with(f): 
    def wrap(g): 
     @functools.wraps(g) 
     def sequenced_func(): 
      f() 
      g() 
     return sequenced_func 
    return wrap 

def func1(): 
    print('func1') 

@sequence_with(func1) 
def func2(): 
    print('func2') 

mais il est probablement pas un bon ajustement conceptuel pour les décorateurs. Conceptuellement, les décorateurs sont censés modifier la fonctionnalité d'une seule fonction qu'ils décorent; une fonction qui enchaîne deux autres fonctions sur un pied d'égalité n'a peut-être pas beaucoup de sens en tant que décoratrice. Par exemple, la nouvelle fonction créée par le décorateur est maintenant sous le nom func2, en remplacement de l'original func2. Cela n'a de sens que pour certains cas d'utilisation spécifiques, alors qu'éviter la syntaxe du décorateur vous donnerait plus de flexibilité.

Il est plus logique de ne pas utiliser la syntaxe de décorateur:

def sequence(f, g): 
    def sequenced_func(): 
     f() 
     g() 
    return sequenced_func 

def func1(): 
    print('func1') 

def func2(): 
    print('func2') 

sequenced_func = sequence(func1, func2)