【问题标题】:IPython: redirecting output of a Python script to a file (like bash >)IPython:将 Python 脚本的输出重定向到文件(如 bash >)
【发布时间】:2013-01-12 07:49:27
【问题描述】:

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

python my_script.py > my_output.txt

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

有一个older page 描述了一个可以编写来执行此操作的函数,但我相信现在有一种我无法找到的内置方法来执行此操作。

【问题讨论】:

  • 似乎缺少功能,它应该比下面的答案更实用

标签: python io ipython


【解决方案1】:

IPython 有自己的 capturing 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 Magics example notebook 中所示。

这是一个简单的上下文管理器,因此您可以编写自己的版本来重定向到文件:

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

【讨论】:

  • 您可以通过在 __init__ 方法中捕获 *args 和 **kw 并将它们传递给打开而不是硬编码写入模式来使其更加健壮。
【解决方案2】:

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

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

(确保>>> 后面没有空格)

【讨论】:

  • PyDev console: using IPython 6.0.0 运行它时,我有ERROR:root:Line magic function '%store' not found.ipython3 中的相同调用效果很好。
  • 如果你得到一个FileNotFoundError: [Errno 2] No such file or directory: '',你可以试试在>>>后面不加空格,像这样:%store VARIABLE >file.txt
【解决方案3】:

虽然这是一个老问题,但我在遇到类似问题时发现了这个问题和答案。

我在筛选IPython Cell magics documentation 后找到的解决方案实际上相当简单。最基本的解决方案是将命令的输出分配给一个变量。

这个简单的两格示例展示了如何做到这一点。在第一个 Notebook 单元格中,我们使用 %%writefile 单元格魔法定义了带有一些输出到 stdout 的 Python 脚本。

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

【讨论】:

    【解决方案4】:

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

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

    使用跟踪器更改文件并建议重新加载文件的文本编辑器很有用 notepad++

    【讨论】:

      【解决方案5】:

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

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

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

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

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          代码好像很多.... 我的解决方案。 redirect output of ipython script into a csv or text file like sqlplus spool 想知道有没有像 oracle sqlplus spool 命令这样简单的方法..?

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-03-22
            • 1970-01-01
            • 2017-08-31
            • 2018-01-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多