2017-09-24 5 views
0

J'ai une fonction en python qui est utilisée dans beaucoup de vues. Plus précisément, il est dans une application django fonctionnant sous uwsgi. La fonction tire juste des données de suivi dans notre base de données. Je voulais créer un décorateur qui désactiverait cette fonction pour un appel spécifique à la vue qui contient la fonction. Essentiellement:Décorateur Python pour désactiver une certaine fonction de plantage

@disable tracking 
def view(request): 
    track(request) //disabled by decorator 

Le décorateur fonctionne en remplaçant la définition globale de la piste par une fonction vide qui ne fait rien. Puisque nous lançons cette commande sous uwsgi, qui est multithread si je remplace une définition globale, elle remplacera la fonction pour tous les threads en cours de traitement, donc j'ai défini le décorateur pour qu'il ne s'activent que si tid et pid sont équivalents. Ici:

def disable_tracking(func): 
    #decorator 
    def inner(*args, **kwargs): 
     original_tracker = pascalservice.track.track 
     anon = lambda *args, **kwargs: None 
     tid = lambda : str(current_thread().ident) 
     pid = lambda : str(getpid()) 
     uid = lambda : tid() + pid() 
     current_uid = uid() 
     cache.set(current_uid, True) 
     switcher = lambda *args, **kwargs: anon(*args, **kwargs) if cache.get(uid()) else original_tracker(*args, **kwargs) 
     pascalservice.track.track = switcher 
     result = func(*args, **kwargs) 
     cache.delete(current_uid) 
     pascalservice.track.track = original_tracker 
     return result 
    return inner 

La chose étrange à propos de cette fonction est décorée que je suis en train de plantages occasionnels et je veux vérifier si ce style de codage est correct car il est un peu non conventionnel.

Répondre

1

Ce que vous faites est appelé patch de singe. Bien que ce ne soit pas une mauvaise pratique, il est souvent difficile d'identifier les bogues, alors utilisez-le avec prudence. Si le décorateur est obligatoire pour une raison quelconque, je suggère d'ajouter un drapeau à l'objet de demande dans votre décorateur et d'ajouter une vérification pour ce drapeau dans votre fonction de piste.

Le décorateur:

def disable_tracking(func): 
    def wrapper(*args, **kwargs): 
    kwargs["request"].pascalservice_do_not_track = true 
    return func(*args, **kwargs) 
    return wrapper 

Début de la fonction piste:

if hasattr(request, "pascalservice_do_not_track"): 
    return 
# do the tracking ... 

Vous pouvez également faire un commentaire de la ligne d'appel piste dans la vue.

+0

Merci pour la réponse. Aussi, je voudrais simplement commenter la fonction de la piste, mais en réalité, elle est appelée dans plusieurs autres fonctions de la vue. Ces fonctions sont réutilisées dans d'autres endroits et ne peuvent donc pas faire de commentaire. –