我想知道如何用Julia语言确定file.jl
是否作为脚本运行,例如在调用中:
bash$ julia file.jl
例如,只有在这种情况下才能启动函数main
。因此,我可以使用include('file.jl')
,而无需实际执行该函数。
具体来说,我正在寻找类似已回答的问题in a python question:
def main():
# does something
if __name__ == '__main__':
main()
编辑:
更具体地说,在非交互式(例如脚本)环境中使用Base.isinteractive
时,方法include('file.jl')
(请参阅here)无法解决问题。
答案 0 :(得分:3)
全局常量PROGRAM_FILE
包含从命令行传递给Julia的脚本名称(调用include
时不会更改)。
另一方面,@__FILE__
宏为您提供了文件的名称。
例如,如果你有一个文件:
a.jl
println(PROGRAM_FILE)
println(@__FILE__)
include("b.jl")
b.jl
println(PROGRAM_FILE)
println(@__FILE__)
您有以下行为:
$ julia a.jl
a.jl
D:\a.jl
a.jl
D:\b.jl
$ julia b.jl
b.jl
D:\b.jl
总结:
PROGRAM_FILE
告诉您Julia开始使用的文件名是什么; @__FILE__
告诉您实际调用宏的文件。答案 1 :(得分:2)
tl; dr版本:
if !isdefined(:__init__) || Base.function_module(__init__) != MyModule
main()
end
<强>解释强>
似乎有些混乱。 Python和Julia在“模块”方面的工作方式截然不同(尽管两者使用相同的术语,原则上它们是不同的)。
在python中,源文件是模块或脚本,具体取决于您选择“加载”/“运行”它的方式:存在样板,用于检测运行源代码的环境,方法是查询执行时嵌入模块的__name__
。例如。如果您有一个名为mymodule.py
的文件,则将其正常导入,然后在模块定义中,变量__name__
自动设置为值mymodule
;但如果您将其作为独立脚本运行(有效地将代码“转储”到“main”模块中),__name__
变量就是全局范围的变量,即__main__
。这种差异使您能够检测如何运行python文件,因此在每种情况下您的行为都会略有不同,这正是样板文件的作用。
然而,在julia中,模块被明确定义为代码。无论您是module
还是using
,运行包含include
声明的文件都会加载该模块;但是在前一种情况下,如果模块已经在工作区中,则不会重新加载模块,而在后一种情况下,就好像你“重新定义”它一样。
模块可以通过特殊的__init__()
函数获得初始化代码,该函数的作用是仅在第一次加载模块时运行(例如,通过using语句导入时)。所以你可以做的一件事是拥有一个独立的脚本,你可以include
直接作为一个独立的脚本运行,或include
在module
定义的范围内,并且它检测模块特定变量的存在,使其在每种情况下表现不同。但它仍然必须是一个独立的文件,与主模块定义分开。
如果您希望模块执行某些操作,那么独立脚本不应该这样做,这很简单:您只需要这样的内容:
module MyModule
__init__() = # do module specific initialisation stuff here
include("MyModule_Implementation.jl")
end
如果您想要相反的情况,您需要一种方法来检测您是否在模块内运行。你可以这样做,例如通过检测属于该特定模块的合适__init__()
函数的存在。例如:
### in file "MyModule.jl"
module MyModule
export fun1, fun2;
__init__() = print("Initialising module ...");
include("MyModuleImplementation.jl");
end
### in file "MyModuleImplementation.jl"
fun1(a,b) = a + b;
fun2(a,b) = a * b;
main() = print("Demo of fun1 and fun2. \n" *
" fun1(1,2) = $(fun1(1,2)) \n" *
" fun2(1,2) = $(fun2(1,2)) \n");
if !isdefined(:__init__) || Base.function_module(__init__) != MyModule
main()
end
如果MyModule
作为模块加载,则main
中的MyModuleImplementation.jl
功能将无法运行。
如果您将MyModuleImplementation.jl
作为独立脚本运行,则main
函数将运行。
所以这是一种达到你想要的效果的方法;但是将模块定义文件作为模块或独立脚本运行是非常不同的;我不认为你可以简单地从代码中“剥离”module
指令,并以这种方式在julia中运行模块的“内容”。