2017-02-28 1 views
1

Je souhaite écrire un décorateur dans python: si une fonction appelée contient print, le décorateur imprime son nom avant que cette fonction ne soit appelée. Je suis familier avec la syntaxe des décorateurs, mais j'ai un problème avec la vérification si une fonction a print en elle-même.Vérifier qu'une fonction utilise la fonction d'impression en python

def preceeding_name(func):   
    @wraps(func) 
    def wrapper(*args, **kwargs): 
     if 'print' in func: 
      print(func.__name__) 
     result = func(*args, **kwargs) 
     return result 
    return wrapper 

Il ne faut pas vérifier si la s » de la fonction print sera effectivement appelé.

+0

trouver si une fonction appelle une autre fonction est [dur] (https://stackoverflow.com/questions/12013399/in-python-determine-if-a -fonction-appelle-une-autre-fonction). Puis-je vous suggérer d'utiliser plutôt le module ['logging'] (https://docs.python.org/3/library/logging.html)? Vous pouvez alors facilement utiliser quelque chose comme '% (funcName) s' lors de la création d'un formateur. – Josh

+0

@Josh, merci, je vais regarder ce fonctionnel – Macaronnos

+0

Cela peut être fait en redéfinissant sys.stdout –

Répondre

3

Cela peut se faire en maintenant le tampon de 'imprimer' de rincer et de le vérifier pour voir si une impression a été faite.

class Out(object): 
    def write(self,s): 
     self.s += s 
    def __init__(self) 
     self.s = '' 

maintenant pour vérifier

def wrapper(*args, **kwargs): 
     our_out = Out() 
     sys.stdout = our_out 
     result = func(*args, **kwargs) 

     if len(our_out.s)>0: 
      sys.stdout = sys.__stdout__ 
      print func.__name__ 
      for s in our_out.s.split('\n'): 
       print s  

     return result 
-1

je ce cas, vous pouvez redéfinir l'impression

def preceeding_name(func): 
    @wraps(func) 
    def wrapper(*args, **kwargs): 

     old_print = print 

     def print(*arg, **kwarg): 
      old_print(func.__name__) 
      old_print(*arg, **kwarg) 

     result = func(*args, **kwargs) 
     return result 
    return wrapper 

EDIT: i test et ce travail

old_print = print 

def preceeding_name(func): 

    def print(*arg, **kwarg): 
     old_print(func.__name__, end='') 
     old_print(*arg, **kwarg) 

    def wrapper(*args, **kwargs): 
     print('') 
     result = func(*args, **kwargs) 
     return result 
    return wrapper 

@preceeding_name 
def a(): 
    print('hi') 


a() 

@preceeding_name 
def b(): 
    print('hi') 


b() 

EDIT2:

old_print = print 


def preceeding_name(func): 
    global print 
    def print(*arg, **kwarg): 
     old_print(func.__name__) 
     old_print(*arg, **kwarg) 

    def wrapper(*args, **kwargs): 
     result = func(*args, **kwargs) 
     return result 

    return wrapper 


@preceeding_name 
def a(): 
    print('hi') 


a() 


@preceeding_name 
def b(): 
    # print('hi') 
    pass 

b() 
+0

Ce décorateur ne fait rien du tout. Tout simplement parce que vous redéfinissez l'impression dans votre portée actuelle ne signifie pas que la fonction décorée utilisera également la nouvelle impression. –

+0

@Rawing nouvelle édition de mon travail de code dans mon ordinateur. J'utilise python 3.4 – sahama

+0

Cela ne vérifie pas si la fonction appelle 'print'. –