我有一个程序通过print语句向控制台输出许多计算和结果。我想编写一些代码来将控制台的所有内容导出(或保存)到一个简单的文本文件中。
我搜索了StackOverflow和其他网站,但我找到了一些方法来重定向print语句直接打印到文件,但我希望程序正常工作,将输出显示到控制台,然后在所有操作后保存其内容完成的程序。
如果重要的话,我正在使用PyCharm和Python2.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保存到文件