web-dev-qa-db-fra.com

rediriger les impressions vers le fichier journal

D'accord. J'ai terminé mon premier programme python. Il contient environ 1000 lignes de code. Pendant le développement, j'ai placé beaucoup d'instructions print avant d'exécuter une commande à l'aide de os.system() dire quelque chose comme,

print "running command",cmd
os.system(cmd)

Maintenant, j'ai terminé le programme. J'ai pensé à les commenter, mais rediriger toutes ces impressions inutiles (je ne peux pas supprimer toutes les instructions print - car certaines fournissent des informations utiles à l'utilisateur) dans un fichier journal sera plus utile? Des astuces ou des conseils.

27
webminal.org

Vous devriez jeter un œil à module de journalisation python


EDIT: Exemple de code:

import logging

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG, filename="logfile", filemode="a+",
                        format="%(asctime)-15s %(levelname)-8s %(message)s")
    logging.info("hello")

Produisez un fichier nommé "logfile" avec du contenu:

2012-10-18 06:40:03,582 INFO     hello
48
user180100
  • La prochaine fois, vous serez plus heureux si, au lieu d'utiliser des instructions print, vous utilisez le module logging dès le début. Il fournit le contrôle que vous souhaitez et vous pouvez le faire écrire sur stdout pendant que c'est toujours là que vous le voulez.

  • Beaucoup de gens ici ont suggéré de rediriger stdout. C'est une solution laide. Il mute un global et - ce qui est pire - il le mute pour l'usage de ce module. Je ferais plus tôt une expression régulière qui change tout print foo à print >>my_file, foo Et mettre my_file vers stdout ou un fichier réel de mon choix.

    • Si vous avez d'autres parties de l'application qui en fait dépendent de l'écriture sur stdout (ou le seront à l'avenir mais vous ne le savez pas encore), cela les brise. Même si vous ne le faites pas, cela donne l'impression que la lecture de votre module fait une chose alors qu'elle en fait une autre si vous avez manqué une petite ligne en haut.
    • L'impression Chevron est assez moche, mais pas aussi moche que de changer temporairement sys.stdout pour le processus.
    • Très techniquement parlant, un remplacement d'expression régulière n'est pas capable de faire cela correctement (par exemple, il pourrait faire de faux positifs si vous êtes à l'intérieur d'un littéral de chaîne multiligne). Cependant, il est apte à fonctionner, gardez simplement un œil dessus.
  • os.system est pratiquement toujours inférieur à l'utilisation du module subprocess. Ce dernier n'a pas besoin d'invoquer le Shell, ne transmet pas les signaux d'une manière qui n'est généralement pas souhaitée et peut être utilisé de manière non bloquante.

8
Mike Graham

Un moyen simple de rediriger stdout et stderr à l'aide du module de journalisation est ici: Comment puis-je dupliquer sys.stdout dans un fichier journal en python?

2
blokeley

Vous pouvez créer un fichier journal et le préparer pour l'écriture. Créez ensuite une fonction:

def write_log(*args):
    line = ' '.join([str(a) for a in args])
    log_file.write(line+'\n')
    print(line)

puis remplacez votre nom de fonction print () par write_log ()

2
AisZuk

Vous pouvez rediriger remplacer sys.stdout avec n'importe quel objet qui a la même interface que sys.stdout, dans l'écriture de cet objet, vous pouvez imprimer sur le terminal et dans le fichier aussi. par exemple. voir cette recette http://code.activestate.com/recipes/119404-print-hook/

2
Anurag Uniyal

Mettre votre propre fichier dans sys.stdout vous permettra de capturer la sortie de texte via print.

1

Juste une note sur le mode ajout vs écriture. Changez le mode de fichier en "w" si vous souhaitez qu'il remplace le fichier journal. J'ai également dû commenter le flux. Ensuite, l'utilisation de logging.info () produisait le fichier spécifié.

if __name__ == '__main__':
    LOG_FORMAT = '%(asctime)s:%(levelname)s ==> %(message)s'
    logging.basicConfig(
        level=logging.INFO,
        filename="logfile",
        filemode="w",
        format=LOG_FORMAT
        #stream=sys.stdout
    )
0
Chris Adams