我想知道是否有办法以编程方式或动态地将一组模块导入Julia?例如,如果我有一个符合启动时存在的某些命名约定的文件列表,我可以使用以下内容获取:
module_files = filter(r"^mod[0-9][0-9].jl$", readdir())
Run Code Online (Sandbox Code Playgroud)
可能会返回一个文件列表["mod00.jl", "mod02.jl", "mod05.jl"],有没有办法导入这些文件中的每个模块.这相当于:
import mod00
import mod02
import mod05
Run Code Online (Sandbox Code Playgroud)
如果我在编写代码时知道那些模块可用,那么在代码中.或者也许还有其他一些方法可以做得更好.任何建议将不胜感激.
更新
我试图通过宏来做到这一点,但没有运气.例如:
macro import_mod(modn)
quote
import $modn
end
end
function test_mimport()
module_files = filter(r"^mod[0-9][0-9].jl$", readdir())
println(module_files)
for modname in factor_files
modn = modname[1:end-3]
println(modn)
@import_mod modn
end
end
Run Code Online (Sandbox Code Playgroud)
当我跑这个时,我明白了ERROR: syntax: invalid "import" statement.我尝试了各种逃避策略,但都失败了.
注意:请参阅用户1712368(Jameson Nash,Julia dev)的回答,这个讨论在julia-users邮件列表和Julia 手册的这个条目中,以了解为什么这不是正确的答案.
这是使用Julia版本0.3.4的多重导入表达式的样子:
julia> parse("import Foo, Bar")
:($(Expr(:toplevel, :($(Expr(:import, :Foo))), :($(Expr(:import, :Bar))))))
julia> dump(ans)
Expr
head: Symbol toplevel
args: Array(Any,(2,))
1: Expr
head: Symbol import
args: Array(Any,(1,))
1: Symbol Foo
typ: Any
2: Expr
head: Symbol import
args: Array(Any,(1,))
1: Symbol Bar
typ: Any
typ: Any
Run Code Online (Sandbox Code Playgroud)
这里是一个做到这一点编程宏,它需要一个modules可能是一个参数:call或:vcat Expr或者Symbol,它必须评估到Vector{Symbol}:
julia> macro dynamic_import(modules)
(modules = eval(modules))::Vector{Symbol}
ex = Expr(:toplevel)
for m in modules
push!(ex.args, Expr(:import, m))
end
return ex
end
Run Code Online (Sandbox Code Playgroud)
你也可以概括这一行:
module_files = filter(r"^mod[0-9][0-9].jl$", readdir())
Run Code Online (Sandbox Code Playgroud)
通过将其抽象为一个函数,该函数将a Regex和String目录路径作为参数并返回Vector{Symbol}:
julia> function needed_modules(rx::Regex, dir::String=".")
module_files = filter(rx, readdir(dir))
module_syms = map(m -> symbol(split(m, '.')[1]), module_files)
end
needed_modules (generic function with 2 methods)
Run Code Online (Sandbox Code Playgroud)
所以你可以像这样使用它:
julia> @dynamic_import [:Mod01, :Mod02] # :vcat expression
julia> rx = r"^Mod[0-9][0-9].jl$";
julia> @dynamic_import needed_modules(rx) # :call expression
julia> modules = needed_modules(rx)
2-element Array{Symbol,1}:
:Mod01
:Mod02
julia> @dynamic_import modules # Symbol
Run Code Online (Sandbox Code Playgroud)
最后,您可以将它全部包装到模块中,以便您可以使用using DynamicImport:
注意:目前我尝试从模块运行相同的示例时得到这个:
julia> using DynamicImport
julia> @dynamic_import [:mod01, :mod02]
julia> rx = r"^mod[0-9][0-9].jl$";
julia> @dynamic_import needed_modules(rx)
ERROR: rx not defined
julia> modules = needed_modules(rx)
2-element Array{Symbol,1}:
:mod01
:mod02
julia> @dynamic_import modules
ERROR: modules not defined
Run Code Online (Sandbox Code Playgroud)
但它工作正常如果我在REPL中定义对象,我想这是一个涉及卫生的问题,这是我没有经历的事情,所以我会在julia-users邮件列表中询问.
小智 3
的函数版本import X是require("X"),所以你应该能够执行以下操作:
function test_mimport()
module_files = filter(r"^mod[0-9][0-9].jl$", readdir())
println(module_files)
for modname in factor_files
modn = modname[1:end-3]
println(modn)
require(modn)
end
end
Run Code Online (Sandbox Code Playgroud)
然后,假设每个都定义了一个同名的模块,您可以将它们收集到一个数组中:
modules = Module[]
...
if isdefined(Main, symbol(modn))
push!(modules, getfield(Main, symbol(modn))
else
warn("importing $modn did not defined a module")
end
...
return modules
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
848 次 |
| 最近记录: |