控制台和文件上的 Python 输出

use*_*563 8 python console file output

我正在编写一个代码来分析 PDF 文件。我想在控制台上显示输出,并在文件中保存输出的副本,我使用以下代码将输出保存在文件中:

import sys
sys.stdout = open('C:\\users\\Suleiman JK\\Desktop\\file.txt',"w")
print "test"
Run Code Online (Sandbox Code Playgroud)

但是我是否也可以将输出显示到控制台,但不使用类,因为我不擅长它们?

Ada*_*dam 8

(这个答案使用 Python 3,如果您更喜欢 Python 2,则必须对其进行调整。)

首先导入 Pythonlogging包(并sys用于访问标准输出流):

import logging
import sys
Run Code Online (Sandbox Code Playgroud)

在您的入口点中,为标准输出流和输出文件设置一个处理程序:

targets = logging.StreamHandler(sys.stdout), logging.FileHandler('test.log')
Run Code Online (Sandbox Code Playgroud)

配置日志包仅输出消息而不输出日志级别:

logging.basicConfig(format='%(message)s', level=logging.INFO, handlers=targets)
Run Code Online (Sandbox Code Playgroud)

现在你可以使用它:

>>> logging.info('testing the logging system')
testing the logging system
>>> logging.info('second message')
second message
>>> print(*open('test.log'), sep='')
testing the logging system
second message
Run Code Online (Sandbox Code Playgroud)


Kev*_*vin 5

sys.stdout可以指向任何具有 write 方法的对象,因此您可以创建一个同时写入文件和控制台的类。

import sys

class LoggingPrinter:
    def __init__(self, filename):
        self.out_file = open(filename, "w")
        self.old_stdout = sys.stdout
        #this object will take over `stdout`'s job
        sys.stdout = self
    #executed when the user does a `print`
    def write(self, text): 
        self.old_stdout.write(text)
        self.out_file.write(text)
    #executed when `with` block begins
    def __enter__(self): 
        return self
    #executed when `with` block ends
    def __exit__(self, type, value, traceback): 
        #we don't want to log anymore. Restore the original stdout object.
        sys.stdout = self.old_stdout

print "Entering section of program that will be logged."
with LoggingPrinter("result.txt"):
    print "I've got a lovely bunch of coconuts."
print "Exiting logged section of program."
Run Code Online (Sandbox Code Playgroud)

结果:

安慰:

Entering section of program that will be logged.
I've got a lovely bunch of coconuts.
Exiting logged section of program.
Run Code Online (Sandbox Code Playgroud)

结果.txt:

I've got a lovely bunch of coconuts.
Run Code Online (Sandbox Code Playgroud)

在某些情况下,此方法可能比codesparkle 更可取,因为您不必将所有现有的 替换printlogging.info. 只需将您想要记录的所有内容放入一个with块中即可。


use*_*459 4

您可以创建一个既打印到控制台又打印到文件的函数。您可以通过切换标准输出来完成此操作,例如:

def print_both(file, *args):
    temp = sys.stdout #assign console output to a variable
    print ' '.join([str(arg) for arg in args]) 
    sys.stdout = file 
    print ' '.join([str(arg) for arg in args])
    sys.stdout = temp #set stdout back to console output
Run Code Online (Sandbox Code Playgroud)

或使用文件写入方法(我建议使用此方法,除非您必须使用标准输出)

def print_both(file, *args):
    toprint = ' '.join([str(arg) for arg in args])
    print toprint
    file.write(toprint)
Run Code Online (Sandbox Code Playgroud)

注意:

  1. 传递给函数的文件参数必须在函数外部打开(例如在程序开始时)并在函数外部关闭(例如在程序结束时)。您应该以附加模式打开它。
  2. 通过将 *args 传递给函数,您可以像传递打印函数一样传递参数。所以你传递参数来打印......

...像这样:

print_both(open_file_variable, 'pass arguments as if it is', 'print!', 1, '!')
Run Code Online (Sandbox Code Playgroud)

否则,您必须将所有内容都变成单个参数,即单个字符串。它看起来像这样:

 print_both(open_file_variable, 'you should concatenate'+str(4334654)+'arguments together')
Run Code Online (Sandbox Code Playgroud)

我仍然建议你学会正确使用类,你会从中受益匪浅。希望这可以帮助。