将所有输出重定向到 Julia 中的文件

Phi*_*lis 5 io julia

我想知道如何将给定调用的任何输出重定向到文件,以便该文件准确包含通常显示在 REPL 中的内容。

我知道Suppressor.jl包是一个有趣的入口点,几乎可以满足我的需要,但例如:

using DataFrames
using Suppressor
output = @capture_out begin
dtf = DataFrame(                 
 [8.04   9.14  7.46   6.58;    
  6.95   8.14  6.77   5.76;   
  8.33   9.26  7.81   8.47])
dtf
end
Run Code Online (Sandbox Code Playgroud)

在输出中不捕获任何内容(或者更准确地说,它捕获"")。为了能够捕获输出,我们必须在这个代码块中编写print(dtf)而不是(而简单的指令实际上会在 REPL 中产生输出)。所以看来这个宏无法捕获任何输出。dtfdtf@capture_out

实际上,当我向 Julia 发送给定的代码块时,我需要将控制台中显示的所有内容重定向到给定的文件:正常输出或错误消息。

实现这一目标的最佳/最简单方法是什么?并且,如果可能的话,对包的依赖最小化?

Bog*_*ski 5

您面临的问题在以下文档字符串中进行了描述display

\n
\n

一般来说,您不能假设显示输出会转到stdout(与print(x)或不同show(x))。例如,display(x) 可以打开一个带有图像的单独窗口。display(x)意思是“以针对当前输出设备的最佳方式显示 x”。如果您想要保证发送到 stdout 的类似 REPL 的文本输出,请改用show(stdout, "text/plain", x)

\n
\n

问题是,如果您只编写dtf输出,则使用display.

\n

不幸的是,我不能推荐这种行为的简单解决方法(例如,您可以修改发送display其输出的目的地,但随后您还会得到例如我认为您不想要的终端转义序列)。

\n

例如,Documenter.jl 需要拦截输出来测试 REPL 结果,不幸的是,它所做的事情非常复杂,您可以在此处查看。

\n

也许有更好的解决方案,但最简单的解决方案是按照display文档的建议进行操作,即使用show(stdout, "text/plain", x)(并且只需替换stdout为自定义流)。

\n

例如,您可以在这里检查我们如何在 DataFrames.jl 中测试输出。

\n

附言。如果您想将 a 传递MatrixDataFrame构造函数并希望自动生成列名:auto,请为列名添加参数,如DataFrame文档所述:

\n
\n

还允许传递向量的向量或矩阵作为第一个参数。Symbol在这种情况下,第二个参数必须是指定列名称的 s 或字符串向量,或者自动:auto生成列名称x1, x2, ... 的符号。

\n
\n

编辑

\n

如果您需要运行外部代码块并获取其输出,那么任务会更简单。唯一的假设是这些代码块没有display显式使用(这不太可能)。在这种情况下,只需使用例如 Suppressor.jl 并将整个代码块包装起来,print如下所示:

\n
julia> output = @capture_out print(begin\n       println("Hello")\n       dtf = DataFrame(                 \n        [8.04   9.14  7.46   6.58;    \n         6.95   8.14  6.77   5.76;   \n         8.33   9.26  7.81   8.47], :auto)\n       dtf\n       end)\n"Hello\\n3\xc3\x974 DataFrame\\n Row \xe2\x94\x82 x1       x2       x3       x4\\n     \xe2\x94\x82 Float64  Float64  Float64  Float64\\n\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\\n   1 \xe2\x94\x82    8.04     9.14     7.46     6.58\\n   2 \xe2\x94\x82    6.95     8.14     6.77     5.76\\n   3 \xe2\x94\x82    8.33     9.26     7.81     8.47"\n\njulia> println(output)\nHello\n3\xc3\x974 DataFrame\n Row \xe2\x94\x82 x1       x2       x3       x4\n     \xe2\x94\x82 Float64  Float64  Float64  Float64\n\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n   1 \xe2\x94\x82    8.04     9.14     7.46     6.58\n   2 \xe2\x94\x82    6.95     8.14     6.77     5.76\n   3 \xe2\x94\x82    8.33     9.26     7.81     8.47\n
Run Code Online (Sandbox Code Playgroud)\n

通过这种方式,您可以获取块内打印的所有内容stdout,并且最后一个表达式的值将被printed (或shown - 无论您喜欢什么)。

\n

display正如所评论的,除非用户在块内调用,否则这将正常工作,但不太可能,因为display通常不显式使用。

\n