如何在程序结束后将控制台打印到文本文件(Python)?

时间:2016-08-25 10:57:07

标签: python console save text-files

我有一个程序通过print语句向控制台输出许多计算和结果。我想编写一些代码来将控制台的所有内容导出(或保存)到一个简单的文本文件中。

我搜索了StackOverflow和其他网站,但我找到了一些方法来重定向print语句直接打印到文件,但我希望程序正常工作,将输出显示到控制台,然后在所有操作后保存其内容完成的程序。

如果重要的话,我正在使用PyCharm和Python2.7

7 个答案:

答案 0 :(得分:3)

好的,通常要完成它,你必须重写python print内置函数。但是......有ipython,它提供了一些钩子。

首先,您需要安装ipython

#bash
sudo pip install ipython

(我正在使用sudo来简单找到我需要访问的文件夹,进一步阅读)

在ipython安装之后,您将拥有ipython扩展文件夹,所以请访问它:

#bash
cd ~/.ipython/extensions/

并在那里创建一个名为print_to_file.py的文件,这里是其内容:

#python
class PrintWatcher(object):
    def __init__(self, ip):
        self.shell = ip

    def post_execute(self):
        with open('/home/turkus/shell.txt', 'a+') as f:
            in_len = len(self.shell.user_ns['In'])
            i = in_len - 1

            in_ = self.shell.user_ns['In'][i]
            out = self.shell.user_ns['Out'].get(i, '')
            # you can edit this line if you want different input in shell.txt
            f.write('{}\n{}\n'.format(in_, out))


def load_ipython_extension(ip):
    pw = PrintWatcher(ip)
    ip.events.register('post_run_cell', pw.post_execute)

保存文件后运行:

#bash
ipython profile create 

# you will get something like that:
[ProfileCreate] Generating default config file: u'/home/turkus/.ipython/profile_default/ipython_config.py'

现在回到设置我们的钩子。我们必须打开在上面的路径下创建的ipython_config.py并放置一些魔法(那里有很多东西,所以转到文件的末尾):

# some commented lines here
c = get_config()
c.InteractiveShellApp.extensions = [
    'print_to_file'
]

保存后,您可以运行ipython并编写代码。您的每个输入都将写在您上面提供的路径下的文件中,在我的情况下是:

/home/turkus/shell.txt

备注

只需从ipython中的'print_to_file'列表中删除c.InteractiveShellApp.extensions,您就可以避免每次ipython_config.py启动时加载您的扩展程序。但请记住,只要输入ipython console:

,您就可以随时加载它
➜  ~ ipython
Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
Type "copyright", "credits" or "license" for more information.

IPython 4.0.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: %load_ext print_to_file

使用print_to_file.py命令后,%reload_ext print_to_file中的任何更改都会反映在打开的ipython shell中,因此您无需退出并再次启动它。

答案 1 :(得分:1)

我不确定如何接收任何编辑器控制台的内容,但这可以通过将print()语句替换为.write

来实现
class Writer(object):
    def __init__(self, out_file, overwrite=False):
        self.file_name = out_file
        self.overwrite = overwrite
        self.history = []

    def write(self, statement):
        self.history.append(statement)
        print statement

    def close(self):
        if self.overwrite:
            self.out_file = open(self.file_name, 'wb')
        else:
            self.out_file = open(self.file_name, 'ab')
        for x in self.history:
            self.out_file.write(x+'/n')
        self.out_file.close()
        self.history = []

p = Writer('my_output_file.txt')
p.write('my string to print and save!') 
p.close() #close the writer to save the contents to a file before exiting

答案 2 :(得分:1)

在我知道了解你的问题后,我认为你搜索了tee命令

python your_program | tee output.txt

这将在控制台和output.txt中显示输出

PS:既然你没有回答我的评论你使用哪个操作系统,我认为你使用的是Linux或MACOS。应该同时工作。我不知道如何在Windows上执行此操作...

答案 3 :(得分:1)

您可以覆盖仍可通过print模块访问的builtins功能

import builtins

f = open("logs.txt", "w")

def print(*args, sep=' ', end='\n', **kwargs):
    builtins.print(*args, sep=sep, end=end, **kwargs)
    f.write(sep.join(*args) + end)

编辑:Python 2的类似解决方案

from __future__ import print_function

class Print:

    def __init__(self, print_function, filename='test', mode='w'):
        self.print_function = print_function
        self.file = open(filename, 'w')

    def __call__(self, *args, **kwargs):
        self.print_function(*args, **kwargs)
        kwargs['file'] = self.file
        self.print_function(*args, **kwargs)

print = Print(print, 'logs.txt')

这会创建一个print函数,您可以将其用作从__future__导入的函数 要在完成所有操作后关闭文件,您必须运行:

print.file.close()

答案 4 :(得分:0)

也许您应该创建一个记录输出的变量,然后将其放入文件中。

例如:

print statement
logger += statement+"\n" #a new line char so each statement is on a new line

with open('file.txt', 'a') as f:
   f.write(statement)

答案 5 :(得分:0)

非常感谢并尊重所有为此问题做出贡献的人。我终于通过对原始代码的最小修改找到了解决这个问题的方法。解决方案由成员@Status和here is its link提供。

虽然我在发布问题之前进行了大量搜索,但受尊敬的成员的答案让我开始精确搜索,尤其是@turkus的贡献,他们表现出色,而@Glostas则睁开眼睛看着& #34;三通"它引导我找到我发布的解决方案(虽然它不包含" tee")。

解决方案the mentioned post稍作修改

1-将以下类放入程序中:

class Logger(object):
"""
Lumberjack class - duplicates sys.stdout to a log file and it's okay
source: https://stackoverflow.com/a/24583265/5820024
"""
def __init__(self, filename="Red.Wood", mode="a", buff=0):
    self.stdout = sys.stdout
    self.file = open(filename, mode, buff)
    sys.stdout = self

def __del__(self):
    self.close()

def __enter__(self):
    pass

def __exit__(self, *args):
    pass

def write(self, message):
    self.stdout.write(message)
    self.file.write(message)

def flush(self):
    self.stdout.flush()
    self.file.flush()
    os.fsync(self.file.fileno())

def close(self):
    if self.stdout != None:
        sys.stdout = self.stdout
        self.stdout = None

    if self.file != None:
        self.file.close()
        self.file = None

2-在程序开始时,在任何打印语句之前,请输入以下行:

my_console = Logger('my_console_file.txt')  # you can change the file's name

3-在程序结束时,在所有打印语句之后,放下这一行:

my_console.close()

我对此进行了测试,并且运行良好,最后我在程序结束后克隆了控制台的输出。

向所有人致以最诚挚的问候,非常感谢所有贡献者。

答案 6 :(得分:-1)

有一个非常明显但不是很优雅的解决方案。

而不是:

print statement 1
calculation
print statement 2

你可以做类似

的事情
sexport =''
calculation
print statement 1
sexport += statement1 + "\n"
calculaztion
print statement 2
sexport += statement 2 

最后只需将sexport保存到文件