将所有输出重定向到 Julia 中的文件
Redirecting all output to file in 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
在输出中不捕获任何内容(或者更准确地说,它捕获 ""
)。为了能够捕获输出,我们必须在此代码块中编写 print(dtf)
而不是 dtf
(而简单的 dtf
指令实际上会在 REPL 中产生输出)。所以似乎这个宏无法捕获任何输出@capture_out
。
实际上,当我将给定的代码块发送给 Julia 时,我需要重定向到给定的文件,所有将显示在控制台中的内容:正常输出或错误消息。
实现该目标的最佳/最简单方法是什么?并且,如果可能的话,对包的依赖性最小?
您遇到的问题在 display
的文档字符串中有描述:
In general, you cannot assume that display output goes to stdout
(unlike print(x)
or show(x)
). For example, display(x) may open up a separate window with an image. display(x)
means "show x in the best way you can for the current output device(s)." If you want REPL-like text output that is guaranteed to go to stdout, use show(stdout, "text/plain", x)
instead.
问题是,如果您只写 dtf
,输出将使用 display
显示。
不幸的是,我不能推荐这种行为的简单解决方法(例如,您可以修改 display
发送其输出的目的地,但随后您也会得到例如终端转义序列,我假设您不会想要)。
例如 Documenter.jl 需要拦截输出以测试 REPL 结果,不幸的是它所做的非常复杂,您可以查看 here.
也许有更好的解决方案,但最简单的方法是按照 display
文档的建议,即改用 show(stdout, "text/plain", x)
(并且只需将 stdout
替换为自定义流)。
例如here你可以检查我们如何在DataFrames.jl.
中测试输出
PS。如果您想将 Matrix
传递给 DataFrame
构造函数并希望自动生成列名,请为列名添加 :auto
参数,如 DataFrame
文档所述:
It is also allowed to pass a vector of vectors or a matrix as as the first argument. In this case the second argument must be a vector of Symbol
s or strings specifying column names, or the symbol :auto
to generate column names x1
, x2
, ... automatically.
编辑
如果您需要 运行 外部代码块并获取它们的输出,那么任务就更简单了。唯一的假设是这些代码块没有明确使用 display
(这不太可能)。在这种情况下,只需使用例如Suppresor.jl 并将整个代码块包装在 print
中,如下所示:
julia> output = @capture_out print(begin
println("Hello")
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], :auto)
dtf
end)
"Hello\n3×4 DataFrame\n Row │ x1 x2 x3 x4\n │ Float64 Float64 Float64 Float64\n─────┼────────────────────────────────────\n 1 │ 8.04 9.14 7.46 6.58\n 2 │ 6.95 8.14 6.77 5.76\n 3 │ 8.33 9.26 7.81 8.47"
julia> println(output)
Hello
3×4 DataFrame
Row │ x1 x2 x3 x4
│ Float64 Float64 Float64 Float64
─────┼────────────────────────────────────
1 │ 8.04 9.14 7.46 6.58
2 │ 6.95 8.14 6.77 5.76
3 │ 8.33 9.26 7.81 8.47
通过这种方式,您可以获取块内打印到 stdout
的所有内容,并且最后一个表达式的值得到 print
ed(或 show
n - 无论您喜欢什么).
如评论所述,除非用户在块内调用 display
,否则这将正常工作,但这种情况不太可能,因为 display
通常不会明确使用。
我想知道如何将给定调用的任何输出重定向到文件,以便该文件准确包含通常会显示到 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
在输出中不捕获任何内容(或者更准确地说,它捕获 ""
)。为了能够捕获输出,我们必须在此代码块中编写 print(dtf)
而不是 dtf
(而简单的 dtf
指令实际上会在 REPL 中产生输出)。所以似乎这个宏无法捕获任何输出@capture_out
。
实际上,当我将给定的代码块发送给 Julia 时,我需要重定向到给定的文件,所有将显示在控制台中的内容:正常输出或错误消息。
实现该目标的最佳/最简单方法是什么?并且,如果可能的话,对包的依赖性最小?
您遇到的问题在 display
的文档字符串中有描述:
In general, you cannot assume that display output goes to
stdout
(unlikeprint(x)
orshow(x)
). For example, display(x) may open up a separate window with an image.display(x)
means "show x in the best way you can for the current output device(s)." If you want REPL-like text output that is guaranteed to go to stdout, useshow(stdout, "text/plain", x)
instead.
问题是,如果您只写 dtf
,输出将使用 display
显示。
不幸的是,我不能推荐这种行为的简单解决方法(例如,您可以修改 display
发送其输出的目的地,但随后您也会得到例如终端转义序列,我假设您不会想要)。
例如 Documenter.jl 需要拦截输出以测试 REPL 结果,不幸的是它所做的非常复杂,您可以查看 here.
也许有更好的解决方案,但最简单的方法是按照 display
文档的建议,即改用 show(stdout, "text/plain", x)
(并且只需将 stdout
替换为自定义流)。
例如here你可以检查我们如何在DataFrames.jl.
中测试输出PS。如果您想将 Matrix
传递给 DataFrame
构造函数并希望自动生成列名,请为列名添加 :auto
参数,如 DataFrame
文档所述:
It is also allowed to pass a vector of vectors or a matrix as as the first argument. In this case the second argument must be a vector of
Symbol
s or strings specifying column names, or the symbol:auto
to generate column namesx1
,x2
, ... automatically.
编辑
如果您需要 运行 外部代码块并获取它们的输出,那么任务就更简单了。唯一的假设是这些代码块没有明确使用 display
(这不太可能)。在这种情况下,只需使用例如Suppresor.jl 并将整个代码块包装在 print
中,如下所示:
julia> output = @capture_out print(begin
println("Hello")
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], :auto)
dtf
end)
"Hello\n3×4 DataFrame\n Row │ x1 x2 x3 x4\n │ Float64 Float64 Float64 Float64\n─────┼────────────────────────────────────\n 1 │ 8.04 9.14 7.46 6.58\n 2 │ 6.95 8.14 6.77 5.76\n 3 │ 8.33 9.26 7.81 8.47"
julia> println(output)
Hello
3×4 DataFrame
Row │ x1 x2 x3 x4
│ Float64 Float64 Float64 Float64
─────┼────────────────────────────────────
1 │ 8.04 9.14 7.46 6.58
2 │ 6.95 8.14 6.77 5.76
3 │ 8.33 9.26 7.81 8.47
通过这种方式,您可以获取块内打印到 stdout
的所有内容,并且最后一个表达式的值得到 print
ed(或 show
n - 无论您喜欢什么).
如评论所述,除非用户在块内调用 display
,否则这将正常工作,但这种情况不太可能,因为 display
通常不会明确使用。