10
votes

équivalent python de '#define Func ()' ou comment commenter une fonction Appel à Python

Mon code Python est entrelacé avec de nombreux appels de fonction utilisées pour (débogage | Profilage | Tracing, etc.) Par exemple: xxx

Je veux #define ces fonctions consommatrices de ressources hors du code. Quelque chose comme l'équivalent C xxx

oui, je sais que le mécanisme de niveau de journalisation du module de journalisation peut être utilisé pour masquer les bouclages ci-dessous Set Niveau de journal. Mais, je demande une manière générale d'avoir les fonctions d'interprète python (qui prenez le temps de courir même si elles ne font pas beaucoup)

Une idée est de redéfinir les fonctions que je veux commenter dans des fonctions vides : xxx

L'idée ci-dessus appelle toujours une fonction et créer une myriade d'autres problèmes


0 commentaires

9 Réponses :


0
votes

Utilisez une variable scopée de module?

à partir de config_module Importer Debug_Flag

et utilisez cette "variable" pour accéder à la fonction de journalisation. Vous construiriez vous-même un module journalier qui utilise le débog_flag pour graver la fonctionnalité de journalisation.


8 commentaires

Donc, je devrais ajouter un chèque avant chaque application de fonction?


@Random Guy: plus sale que ce n'est déjà avec toutes ces déclarations de débogage ??


@JLDUPONT: Je dois-je modifier tous les appels pour vous connecter à ma classe d'emballage?


@cschol: Le débogage est l'exemple le plus courant que je puisse penser. Mais cette caractéristique magique que je demande est bonne pour d'autres choses telles que le vrai virage / désactivé des fonctionnalités


@Random Guy: Pas vraiment: utilisez simplement le module pour configurer la fonctionnalité de journalisation en fonction du débog_flag .


@jldupont: Je ne suis pas sûr de vous comprendre (je suis un nouveaubee). Comment puis-je empêcher Python d'appeler / interpréter l'une des fonctions de journalisation (ou tout autre module, fonctions, etc.) à l'aide du drapeau de débogage?


@Random Guy: Avez-vous lu " noreferrer"> docs.python.org/library/logging. HTML # Configuration de la journalisation "? Vous pouvez configurer le module de journalisation en fonction du débog_flag que j'ai suggéré.


@jldupont: oui je le lis. Je ne me suis pas fait clairement: je sais que vous pouvez configurer le module de journalisation pour ignorer certaines demandes de journalisation, mais, les appels de la fonction de demande de journalisation (par exemple la journalisation.debug ()) sont toujours en cours de réalisation. Je ne cherche pas une solution spécifique aux fonctions du module de journalisation, BOGE Un moyen général de commenter une fonction de Python



0
votes

Je pense que cela supprime complètement l'appel sur une fonction n'est pas posable, car Python fonctionne d'une manière différente de ce que C. Le #define a lieu dans le pré-compilateur, avant que le code ne soit compilé. En Python, il n'y a pas de telle chose.

Si vous souhaitez supprimer complètement l'appel à déboguer dans un environnement de travail, je pense que le seul moyen de changer le code avant exécution. Avec un script précédant l'exécution, vous pouvez commenter / définir les lignes de débogage.

quelque chose comme ceci:

fichier logging.py xxx

fichier call_log.py xxx < / Pré>

Bien sûr, il a ses problèmes, spécialement s'il y a beaucoup de modules et complexes, mais pourrait être utilisable si vous devez absolument éviter l'appelant à une fonction.


0 commentaires

17
votes

Python n'a pas de préprocesseur, bien que vous puissiez exécuter votre source de python à travers un prétraiteur externe pour obtenir le même effet - par exemple. sed "/logging.debug/d" code> va éteindre toutes les commandes de journalisation du débogage. Ce n'est pas très élégant mais vous finirez par avoir besoin d'une sorte de système de construction pour exécuter tous vos modules via le pré-processeur et créer peut-être une nouvelle arborescence de répertoires des fichiers .PY traités avant d'exécuter le script principal.

Alternativement si vous Mettez toutes vos relevés de débogage dans un si __debug __: code> Block, ils seront optimisés lorsque Python est exécuté avec le drapeau -o (optimiser) drapeau. P>

comme à l'écart, j'ai vérifié le Code avec le module DIS pour vous assurer qu'il a été optimisé. J'ai découvert que p> xxx pré>

et p> xxx pré>

est optimisé, mais p> xxx pré >

n'est pas. C'est parce que FALSE est un objet Python régulier, et vous pouvez en fait faire cela: P>

>>> def f():
...     if False: print( "illogical")
... 
>>> dis.dis(f)
  2           0 LOAD_CONST               0 (None) 
              3 RETURN_VALUE         


2 commentaires

Précendeur si 0: | Si débogage : | Si la variable: + l'optimisation, que ce soit par un script ou un bon éditeur, une meilleure idée peut être la meilleure idée (meilleure que celle de l'avant-rapport qui ne gère pas les relevés multi-lignes). peut-être python n'est pas parfait après tout


@Dave: Un joli virus de Python injecterait la ligne 'Faux, True = True, False' dans le code. Des choses merveilleuses peuvent arriver



-1
votes

Vous ne pouvez pas sauter em> appels de fonction. Vous pouvez redéfinir ces comme vides cependant, par exemple. En créant un autre objet de journalisation qui fournit la même interface, mais avec des fonctions vides.

Mais de loin l'approche la plus propre consiste à ignorer les messages journaux à faible priorité (comme vous l'avez suggéré): P>

logging.root.setLevel(logging.CRITICAL)


2 commentaires

Je me suis fait clairement clair. Je cherche un hack python à usage général pour "commenter" les appels de fonction. C'est-à-dire que je veux que les fonctions "commentées" ne soient même pas appelées. Votre suggestion n'élimine pas l'appel de la fonction à la journalisation.debug (). La fonction est appelée et fait du traitement. C'est ce que je veux éviter


Vous vous êtes rendu clair, mais je ne pense pas que ce soit pythonique de faire ce que vous avez demandé.



0
votes

Avant de le faire, avez-vous profilé de vérifier que la journalisation prend réellement une durée importante? Vous constaterez peut-être que vous passez plus de temps à essayer de supprimer les appels que vous économisez.

Suivant, avez-vous essayé quelque chose comme PSYCO ? Si vous avez des choses configurées afin que la journalisation est désactivée, Psyco peut peut-être optimiser la plupart des frais généraux d'appeler la fonction de journalisation, remarquant qu'il reviendra toujours sans action.

Si vous trouvez toujours une journalisation prenant une quantité de temps appréciable, vous pouvez alors vouloir envisager de remplacer la fonction de journalisation dans les boucles critiques, éventuellement en liant une variable locale à la fonction de journalisation ou à une fonction factice comme appropriée (ou par Vérification de rien avant de l'appeler).


1 commentaires

Je ne me suis pas rendu clair. J'ai utilisé le module de journalisation et les performances comme exemple. Il existe d'autres raisons de vouloir dire des fonctions, par exemple, lors de l'élimination d'une fonctionnalité du code



1
votes

Eh bien, vous pouvez toujours mettre en œuvre votre propre préprocesseur simple qui fait l'affaire. Ou encore mieux, vous pouvez utiliser un déjà existant. Dites http://code.google.com/p/preprocess/


0 commentaires

2
votes

Bien que je pense que la question est parfaitement claire et valide (malgré les nombreuses réponses qui suggèrent autrement), la réponse courte est "Il n'y a pas de support en python pour cela".

La seule solution potentielle autre que le Pré-processeur Suggestion serait d'utiliser un Bytecode piratage . Je ne vais même pas commencer à imaginer comment cela devrait fonctionner en termes d'API de haut niveau, mais à un niveau bas, vous pouvez imaginer d'examiner des objets de code pour des séquences particulières d'instructions et de les réécrire à les éliminer. p>

Par exemple, regardez les deux fonctions suivantes: p> xxx pré>

ici, vous pouvez numériser pour le load_global code> de déboguer code> et l'éliminez-le et tout jusqu'à la cible Jump_IF_False CODE> CIBLE. P>

Celui-ci est la fonction de débogage de style C () traditionnelle qui est bien effréné par un Préprocesseur: P>

>>> def func2():
...    debug('bar', baz)
>>> dis.dis(func2)
  2           0 LOAD_GLOBAL              0 (debug)
              3 LOAD_CONST               1 ('bar')
              6 LOAD_GLOBAL              1 (baz)
              9 CALL_FUNCTION            2
             12 POP_TOP
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE


0 commentaires

0
votes

Définir une fonction qui ne fait rien, c'est-à-dire xxx pré>

surcharger toutes les fonctions que vous souhaitez vous débarrasser de votre fonction, ALA P>

logging.debug = nuzzing


2 commentaires

Ma question initiale comprend une variante de cette solution


Ouais mais en laissant la fonction de votre espace d'emploi, appelez-vous de manière récursive, vous laissez la porte ouverte pour la méchanceté immédiate (pile de profondeur maximale d'appel dépassé). Le récent compilateur CPPHON est suffisamment intelligent pour réduire toute fonctionnalité qui ne passe en aucun cas à un COPNOP de toute façon, de sorte que tous les appels sont efficacement commentés. Je n'imagine pas que tu vas trouver une meilleure solution.



0
votes

J'aime la solution "si __debug_", sauf que cela le mettant devant chaque appel est un peu distrayant et moche. J'ai eu ce même problème et le surmonté en écrivant un script qui analyse automatiquement vos fichiers source et remplace les instructions de la journalisation avec les instructions de réussite (et commenté les copies des relevés de journalisation). Il peut également annuler cette conversion.

Je l'utilise lorsque je déploiement du nouveau code dans un environnement de production lorsqu'il y a beaucoup de déclarations de journalisation que je n'ai pas besoin dans un réglage de la production et qui affectent les performances.

Vous pouvez trouver le script ici: http://dound.com/2010 / 02 / Python-Logging-Performance /


0 commentaires