同时打印到屏幕和写入文件 [英] Printing to screen and writing to a file at the same time

查看:73
本文介绍了同时打印到屏幕和写入文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在网上找到了一些通常有效的代码,但我想在同一个程序中多次使用它(将不同的内容写入不同的文件,同时始终打印到屏幕上).

也就是说,当它关闭时,我认为 sys.stdout 关闭,因此根本打印,再次使用该类失败.我尝试重新导入 sys 和其他愚蠢的东西,但我无法让它工作.

这是网站和代码groups.google.com/group/comp.lang.python/browse_thread/thread/d25a9f5608e473af/

导入系统类 MyWriter:def __init__(self, stdout, 文件名):self.stdout = 标准输出self.logfile = 文件(文件名,'a')定义写(自我,文本):self.stdout.write(文本)self.logfile.write(文本)定义关闭(自我):self.stdout.close()self.logfile.close()writer = MyWriter(sys.stdout, 'log.txt')sys.stdout = 编写器打印测试"

解决方案

你试图重现 Python 标准库做得很好的东西;请检查日志模块.

使用此模块,您可以完全按照自己的意愿做事,而且以更简单、标准和可扩展的方式进行.您可以按以下步骤操作(此示例是 记录食谱):

<块引用>

假设你想用不同的消息登录到控制台和文件格式和在不同的情况下.说你想记录消息具有 DEBUG 和更高级别的文件,以及级别的消息INFO 及更高版本到控制台.我们还假设文件应该包含时间戳,但控制台消息不应该.就是这样你可以做到这一点:

导入日志# 设置日志记录到文件 - 有关更多详细信息,请参阅上一节logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',datefmt='%m-%d %H:%M',文件名='/temp/myapp.log',文件模式='w')# 定义一个将 INFO 消息或更高级别写入 sys.stderr 的处理程序控制台 = logging.StreamHandler()console.setLevel(logging.INFO)# 设置一个更易于控制台使用的格式formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')# 告诉处理程序使用这种格式console.setFormatter(格式化程序)# 将处理程序添加到根记录器logging.getLogger().addHandler(控制台)# 现在,我们可以登录到根记录器或任何其他记录器.首先是根...logging.info('寒鸦喜欢我的石英大狮身人面像.')# 现在,定义一些其他记录器,它们可能代表您的区域# 应用:logger1 = logging.getLogger('myapp.area1')logger2 = logging.getLogger('myapp.area2')logger1.debug('快速的和风打击,恼人的愚蠢的吉姆.')logger1.info('跳斑马的速度有多快.')logger2.warning('从江湖骗子那里抢了钱的监狱热情的泼妇.')logger2.error('五位拳师跳得很快.')

<块引用>

当你运行这个时,你会在控制台看到

root : INFO 寒鸦喜欢我的大石英狮身人面像.myapp.area1 : INFO 斑马跳跃的速度有多快.myapp.area2 :警告从庸医那里抢钱的监狱热情的泼妇.myapp.area2 : ERROR 五位拳师跳得很快.

<块引用>

在文件中你会看到类似

10-22 22:19 root INFO 寒鸦喜欢我的大石英狮身人面像.10-22 22:19 myapp.area1 DEBUG 快速的和风吹来,恼人的愚蠢的吉姆.10-22 22:19 myapp.area1 INFO 斑马跳跃的速度有多快.10-22 22:19 myapp.area2 WARNING 从江湖骗子那里抢钱的监狱里热情洋溢的泼妇.10-22 22:19 myapp.area2 ERROR 五位拳师跳得很快.

<块引用>

如您所见,DEBUG 消息仅显示在文件中.另一个消息被发送到两个目的地.

此示例使用控制台和文件处理程序,但您可以使用任何您选择的处理程序的数量和组合.

I found some code online that generally works, but I want to use it multiple times in the same program (write different things to different files, while still printing to the screen the whole time).

That is to say, when it closes, I think sys.stdout closes, so printing at all, and using this class again fails. I tried reimporting sys, and other dumb stuff, but I can't get it to work.

Here's the site, and the code groups.google.com/group/comp.lang.python/browse_thread/thread/d25a9f5608e473af/

import sys

class MyWriter:

    def __init__(self, stdout, filename):
        self.stdout = stdout
        self.logfile = file(filename, 'a')

    def write(self, text):
        self.stdout.write(text)
        self.logfile.write(text)

    def close(self):
        self.stdout.close()
        self.logfile.close()

writer = MyWriter(sys.stdout, 'log.txt')
sys.stdout = writer

print 'test' 

解决方案

You are trying to reproduce poorly something that is done very well by the Python Standard Library; please check the logging module.

With this module you can do exactly what you want, but in a much simpler, standard, and extensible manner. You can proceed as follows (this example is a copy/paste from the logging cookbook):

Let’s say you want to log to console and file with different message formats and in differing circumstances. Say you want to log messages with levels of DEBUG and higher to file, and those messages at level INFO and higher to the console. Let’s also assume that the file should contain timestamps, but the console messages should not. Here’s how you can achieve this:

import logging

# set up logging to file - see previous section for more details
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                    datefmt='%m-%d %H:%M',
                    filename='/temp/myapp.log',
                    filemode='w')
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# set a format which is simpler for console use
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger().addHandler(console)

# Now, we can log to the root logger, or any other logger. First the root...
logging.info('Jackdaws love my big sphinx of quartz.')

# Now, define a couple of other loggers which might represent areas in your
# application:

logger1 = logging.getLogger('myapp.area1')
logger2 = logging.getLogger('myapp.area2')

logger1.debug('Quick zephyrs blow, vexing daft Jim.')
logger1.info('How quickly daft jumping zebras vex.')
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')

When you run this, on the console you will see

root        : INFO     Jackdaws love my big sphinx of quartz.
myapp.area1 : INFO     How quickly daft jumping zebras vex.
myapp.area2 : WARNING  Jail zesty vixen who grabbed pay from quack.
myapp.area2 : ERROR    The five boxing wizards jump quickly.

and in the file you will see something like

10-22 22:19 root         INFO     Jackdaws love my big sphinx of quartz.
10-22 22:19 myapp.area1  DEBUG    Quick zephyrs blow, vexing daft Jim.
10-22 22:19 myapp.area1  INFO     How quickly daft jumping zebras vex.
10-22 22:19 myapp.area2  WARNING  Jail zesty vixen who grabbed pay from quack.
10-22 22:19 myapp.area2  ERROR    The five boxing wizards jump quickly.

As you can see, the DEBUG message only shows up in the file. The other messages are sent to both destinations.

This example uses console and file handlers, but you can use any number and combination of handlers you choose.

这篇关于同时打印到屏幕和写入文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆