有没有办法在 Julia Jupyter 笔记本中抑制函数内部的输出?

Is there a way to suppress outputs inside a function in a Julia Jupyter notebook?

在 Jupyter 单元格中,我想调用一个包含 println@show 等的函数,但我不想看到这些输出。有没有办法在抑制输出的同时调用函数?我知道 ;,但我的理解是 ; 仅影响 return 值。

例如,假设您有一个函数

function testOutputs()
    @show("Show macro still showing")
    println("Println still showing")
    a = 1 + 2
end

在单元格中调用 testOutputs(); 结果:

"Show macro still showing" = "Show macro still showing"
Println still showing

我希望它什么都不打印。

没有人会阻止您让这些功能变得无用。它警告您必须从 Base 导入才能实际覆盖它们。

julia> import Base.println

julia> println(args...) = nothing
println (generic function with 3 methods)

julia> import Base.@show

julia> macro show(args...)
       return :(nothing) # TODO: make this a pass thru instead of a removal
       end
@show (macro with 1 method)

julia> testOutputs()
3

julia> testOutputs();

有时程序员会在表达式中间放置一个 @show,这种宏覆盖会中断这些行。

恕我直言,更好的替代方法是使用 Memento.jl 之类的日志记录库或 julia 的内置日志记录库。他们有单行功能,可以通过他们的机制大量禁用日志记录。

https://docs.julialang.org/en/v1/stdlib/Logging/
https://docs.julialang.org/en/v1/stdlib/Logging/#Logging.disable_logging

julia> @debug "Hello World"

julia> @info "Hello World"
[ Info: Hello World

julia> @warn "Hello World"
┌ Warning: Hello World
└ @ Main REPL[10]:1

julia> @error "Hello World"
┌ Error: Hello World
└ @ Main REPL[11]:1

julia> using Logging

julia> Logging.disable_logging(Logging.Error)
LogLevel(2001)

julia> @debug "Hello World"

julia> @info "Hello World"

julia> @warn "Hello World"

julia> @error "Hello World"

https://invenia.github.io/Memento.jl/latest/

Memento.config!("emergency")

或者在没有任何其他库的情况下,在名为 debug_print 的文件顶部创建一个全局标志,并在需要时交换它。

julia> global debug_print = true
true

julia> function testOutputs()
           debug_print && @show("Show macro still showing")
           debug_print && println("Println still showing")
           a = 1 + 2
       end
testOutputs (generic function with 1 method)

julia> testOutputs();
"Show macro still showing" = "Show macro still showing"
Println still showing

julia> debug_print = false
false

julia> testOutputs();

正如 phyatt 的回答所强调的那样,库代码使用可配置的日志记录机制通常会更好。但是,有时您想要调用的代码,无论出于何种原因,都直接写入 stdout。处理这些情况的一种方法是使用 redirect_stdout.

例如:

real_stdout = stdout
(rd, wr) = redirect_stdout();
# Noisy code here
redirect_stdout(real_stdout)

您可能希望将其放入函数或宏中,或者简单地使用 Suppressor.jl a library that provides these macros. If you want to capture the output the way the ipython %%capture magic does you can have a look at @capture_out in Suppressor.jl, and this forum thread