我有一个要在 IPython 中运行的 Python 脚本。我想将输出重定向(写入)到一个文件,类似于:
python my_script.py > my_output.txt
当我在 IPython 中运行脚本时,我该怎么做,例如execfile('my_script.py')
有一个较旧的页面描述了可以编写来执行此操作的函数,但我相信现在有一种内置的方法来执行此操作,我只是找不到。
IPython 有自己的上下文管理器来捕获 stdout/err,但它不会重定向到文件,它会重定向到一个对象:
from IPython.utils import io
with io.capture_output() as captured:
%run my_script.py
print captured.stdout # prints stdout from your script
并且此功能在%%capture
cell-magic 中公开,如Cell Magics 示例笔记本中所示。
它是一个简单的上下文管理器,因此您可以编写自己的版本来重定向到文件:
class redirect_output(object):
"""context manager for reditrecting stdout/err to files"""
def __init__(self, stdout='', stderr=''):
self.stdout = stdout
self.stderr = stderr
def __enter__(self):
self.sys_stdout = sys.stdout
self.sys_stderr = sys.stderr
if self.stdout:
sys.stdout = open(self.stdout, 'w')
if self.stderr:
if self.stderr == self.stdout:
sys.stderr = sys.stdout
else:
sys.stderr = open(self.stderr, 'w')
def __exit__(self, exc_type, exc_value, traceback):
sys.stdout = self.sys_stdout
sys.stderr = self.sys_stderr
你会调用它:
with redirect_output("my_output.txt"):
%run my_script.py
要在使用 IPython 时快速存储变量中包含的文本,请%store
使用>
or >>
:
%store VARIABLE >>file.txt
(追加)
%store VARIABLE >file.txt
(覆盖)
(确保紧跟在>
or后面没有空格>>
)
虽然这是一个老问题,但当我面临类似问题时,我发现了这个问题和答案。
我在筛选IPython Cell 魔法文档后发现的解决方案实际上相当简单。最基本的解决方案是将命令的输出分配给一个变量。
这个简单的两格示例展示了如何做到这一点。在第一个 Notebook 单元中,我们定义了 Python 脚本,其中包含一些输出以stdout
利用%%writefile
单元魔法。
%%writefile output.py
print("This is the output that is supposed to go to a file")
然后我们运行该脚本,就像它使用!
操作符从 shell 运行一样。
output = !python output.py
print(output)
>>> ['This is the output that is supposed to go to a file']
然后你可以很容易地利用%store
魔法来持久化输出。
%store output >output.log
但是请注意,命令的输出作为行列表保留。您可能想"\n".join(output)
在存储输出之前调用。
使用此代码将输出保存到文件
import time
from threading import Thread
import sys
#write the stdout to file
def log():
#for stop the thread
global run
while (run):
try:
global out
text = str(sys.stdout.getvalue())
with open("out.txt", 'w') as f:
f.write(text)
finally:
time.sleep(1)
%%capture out
run = True
print("start")
process = Thread(target=log, args=[]).start()
# do some work
for i in range(10, 1000):
print(i)
time.sleep(1)
run= False
process.join()
使用跟踪器更改文件并建议重新加载文件(如记事本++)的文本编辑器很有用
为了只运行一个脚本,我会在 bash 中进行重定向
ipython -c "execfile('my_script.py')" > my_output.txt
在python 3上, execfile 不再存在,因此请改用它
ipython -c "exec(open('my_script.py').read())" > my_output.txt
小心使用双引号和单引号。
有一种用文件对象覆盖的 hacky 方法sys.stdout
,sys.stderr
但这真的不是一个好方法。真的,如果你想控制 python 内部的输出,你需要实现某种日志记录和/或输出处理系统,你可以通过命令行或函数参数而不是使用print
语句来配置这些系统。
似乎有很多代码....我的解决方案。 将 ipython 脚本的输出重定向到 csv 或文本文件,如 sqlplus spool 想知道有没有像 oracle sqlplus spool 命令这样的简单方法..?