【问题标题】:Within a Julia script, can you tell whether the script has been imported or executed directly?在 Julia 脚本中,你能判断脚本是被导入还是直接执行的吗?
【发布时间】:2013-01-22 15:51:42
【问题描述】:

python 中的一个常见约定是将脚本的主要功能构造如下,因此它既可以作为脚本直接运行,也可以在导入时不执行main() 导入:

def main():
    do_stuff()

if __name__ == '__main__':
    main()

在 Julia 中是否设置了类似的变量,以便脚本可以知道它是使用 require("script.jl") 导入的还是直接执行的?

例如,假设我有两个脚本,a.jlb.jl,还有一个 magic_function(),其行为如下:

a.jl

println("Did we execute a.jl directly? ", magic_function())

b.jl

require("a.jl")

执行以下命令会导致...

> julia a.jl
Did we execute a.jl directly? true
> julia b.jl
Did we execute a.jl directly? false

目前的Julia发行版中是否存在magic_function()这样的函数?

【问题讨论】:

    标签: julia


    【解决方案1】:

    Julia 官方文档建议这样做:

    if abspath(PROGRAM_FILE) == @__FILE__
    
        # do something only this file is executed. 
        do_something()
    
    end
    

    do_something函数只在代码执行时执行,从其他代码导入代码时不执行。

    Ref:"如何检查当前文件是否作为主脚本运行?" https://docs.julialang.org/en/v1/manual/faq/#How-do-I-check-if-the-current-file-is-being-run-as-the-main-script?-1

    【讨论】:

    • 不完全。 PROGRAM_FILE 在默认 REPL 中是 "",所有字符串都包含 ""。也可能存在其他基于路径的误报。
    • 这不起作用:当我运行 ./script.jl 时,@__FILE__/home/me/script.jlPROGRAM_FILE./script.jl。后者不包含在前者中,因此条件为假。 @oyd11 的上述解决方案始终有效。
    • 以目前的形式和截至 2020-2021 年,我认为这应该是公认的答案
    【解决方案2】:

    我用

    if ""!=PROGRAM_FILE && realpath(@__FILE__) == realpath(PROGRAM_FILE)
    

    我似乎在上面投票否决了类似的解决方案,我想知道有什么问题,我将它用于一些单元测试和一些也是命令行的模块chmod 755utils

    (刚刚为“REPL include”案例添加了""!=PROGRAM_FILE,变得有点拗口)

    【讨论】:

      【解决方案3】:

      虽然isinteractive() 可以让您辨别 REPL 是在命令行上运行/导入到其他代码中,但无法获得与 Python 的 if __name__ == '__main__' 完全相同的功能。

      这似乎没有计划为一项功能。请参阅此discussion on the mailing list。 (从 2013 年 6 月开始)

      【讨论】:

        【解决方案4】:

        这是我找到的最佳解决方案:

        module mymod
            # stuff here
        end
        
        if length(ARGS)>0 && ARGS[1] == "--run"
            using mymod
            mymod.myfunction()
        end
        

        然后你可以像往常一样导入模块,但你可以像这样从命令行调用类似可执行文件的行为:

        julia mycode.jl --run
        

        如果您没有其他参数要传递给脚本,if 语句甚至可以缩短为:

        if ARGS == ["--run"]
            # etc...
        end
        

        【讨论】:

        • 如果我编写一个脚本abc.jl 导入您的mycode.jl 并执行julia abc.jl,那么您的mycode.jl 仍然会认为它正在直接运行,这是不正确的。如果是这样,那么你的答案不等同于 Python 的方法。
        【解决方案5】:

        您需要isinteractive() 函数。在 REPL 中尝试一下,将其结果与从脚本中调用它的结果进行比较,例如在此 BASH 单行代码中:julia -e "println(isinteractive())"

        【讨论】:

        • 那是一回事吗? julia test.jl 脚本只是 println(isinteractive()) 将打印 false,而 python test.py / print __name__ == '__main__' 将打印 True
        • 这不是我所需要的:isinteractive() 测试它是从 REPL 执行还是从运行 julia my_script.jl 执行,而不是我运行 julia my_script.jl 或 julia script_that_requires_my_script.jl。为清楚起见更新问题。
        猜你喜欢
        • 2019-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        • 2012-02-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多