40

我有一个要在 IPython 中运行的 Python 脚本。我想将输出重定向(写入)到一个文件,类似于:

python my_script.py > my_output.txt

当我在 IPython 中运行脚本时,我该怎么做,例如execfile('my_script.py')

有一个较旧的页面描述了可以编写来执行此操作的函数,但我相信现在有一种内置的方法来执行此操作,我只是找不到。

4

7 回答 7

45

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

并且此功能在%%capturecell-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
于 2013-01-28T23:53:11.483 回答
14

要在使用 IPython 时快速存储变量中包含的文本,请%store使用>or >>

%store VARIABLE >>file.txt (追加)
%store VARIABLE >file.txt(覆盖)

(确保紧跟在>or后面没有空格>>

于 2017-05-17T16:59:42.000 回答
2

虽然这是一个老问题,但当我面临类似问题时,我发现了这个问题和答案。

我在筛选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)在存储输出之前调用。

于 2019-08-09T06:03:02.777 回答
1

使用此代码将输出保存到文件

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()

使用跟踪器更改文件并建议重新加载文件(如记事本++)的文本编辑器很有用

于 2020-01-02T19:48:00.443 回答
0

为了只运行一个脚本,我会在 bash 中进行重定向

ipython -c "execfile('my_script.py')" > my_output.txt

python 3上, execfile 不再存在,因此请改用它

ipython -c "exec(open('my_script.py').read())" > my_output.txt

小心使用双引号和单引号。

于 2020-06-17T10:16:27.117 回答
-1

有一种用文件对象覆盖的 hacky 方法sys.stdoutsys.stderr但这真的不是一个好方法。真的,如果你想控制 python 内部的输出,你需要实现某种日志记录和/或输出处理系统,你可以通过命令行或函数参数而不是使用print语句来配置这些系统。

于 2013-01-28T21:00:50.347 回答
-1

似乎有很多代码....我的解决方案。 将 ipython 脚本的输出重定向到 csv 或文本文件,如 sqlplus spool 想知道有没有像 oracle sqlplus spool 命令这样的简单方法..?

于 2016-10-14T17:19:59.980 回答