在Julia中以编程/动态方式导入模块

在Julia中以编程/动态方式导入模块,julia,Julia,我想知道是否有一种方法可以通过编程或动态地将一组模块导入Julia?例如,如果我有一个符合启动时出现的命名约定的文件列表,我可以使用如下方式获取: module_files = filter(r"^mod[0-9][0-9].jl$", readdir()) 它可能返回文件列表[“mod00.jl”、“mod02.jl”、“mod05.jl”],是否有方法导入这些文件中的每个模块。这相当于: import mod00 import mod02 import mod05 在代码中,如果我在编写

我想知道是否有一种方法可以通过编程或动态地将一组模块导入Julia?例如,如果我有一个符合启动时出现的命名约定的文件列表,我可以使用如下方式获取:

module_files = filter(r"^mod[0-9][0-9].jl$", readdir())
它可能返回文件列表
[“mod00.jl”、“mod02.jl”、“mod05.jl”]
,是否有方法导入这些文件中的每个模块。这相当于:

import mod00
import mod02
import mod05
在代码中,如果我在编写代码时知道这些模块是可用的。或者也许有其他更好的方法。如有任何建议,将不胜感激

更新

我试图通过宏来实现这一点,但没有成功。例如:

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

当我运行此命令时,我得到
错误:语法:无效的“import”语句
。我尝试了各种逃避策略,但都以同样的方式失败。

我对这个解决方案不感兴趣,但它似乎奏效了。基本上,我会动态创建一个包含导入语句的临时文件,然后
将其包含进去。因此:

function test_mimport()
    module_files = filter(r"^mod[0-9][0-9].jl$", readdir())
    path, f = mktemp()
    for modname in module_files
        modn = splitext(modname)[1]
        write(f, "import $modn\n")
    end

    close(f)
    include(path)
    rm(path)

end
我很想知道是否有一种更为惯用的策略,因为我对Julia还不熟悉,只是涉猎了一下它的功能

编辑

设置临时文件的策略可能是不必要的,因为Julia还提供了一种方法


在Julia用户列表中,@Isaiah还使用了
eval(Expr(:import,symbol(modn))
导入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
然后,假设每个模块都定义了相同名称的模块,则可以将它们收集到一个数组中:

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

注意:请参考用户1712368(Jameson Nash,Julia dev)的答案,这是Julia用户邮件列表和Julia的条目,了解为什么这不是正确答案

这是使用Julia版本0.3.4时多重导入表达式的外观:

julia>parse(“导入Foo,Bar”)
:($(Expr(:toplevel,:($(Expr(:import,:Foo))),:($(Expr(:import,:Bar()))))
julia>转储(ans)
Expr
头部:符号顶层
args:数组(任意,(2,))
1:Expr
标题:符号导入
args:数组(任意,(1,))
1:符号Foo
典型:有吗
2:Expr
标题:符号导入
args:数组(任意,(1,))
1:符号栏
典型:有吗
典型:有吗
这是一个以编程方式执行此操作的宏,它接受一个
modules
参数,该参数可以是
:call
:vcat
Expr
符号
,必须计算为
向量{Symbol}

julia>宏动态导入(模块)
(modules=eval(modules))::向量{Symbol}
ex=Expr(:顶级)
对于模中的m
推(例如args,Expr(:import,m))
结束
退换货
结束
您还可以概括这一行:

module\u files=filter(r“^mod[0-9][0-9].jl$”,readdir())
通过将其抽象为一个函数,该函数将
Regex
String
目录路径作为参数,并返回
向量{Symbol}

julia>所需函数\u模块(rx::Regex,dir::String=“.”)
模块_文件=过滤器(rx、readdir(dir))
模块syms=map(m->symbol(拆分(m’,.)[1]),模块文件)
结束
所需的_模块(具有2种方法的通用函数)
所以你可以这样使用它:

julia>@dynamic_import[:Mod01,:Mod02]#:vcat表达式
julia>rx=r“^Mod[0-9][0-9].jl$”;
julia>@dynamic_import needed_modules(rx)#:调用表达式
julia>模块=需要的模块(rx)
二元数组{符号,1}:
:Mod01
:Mod02
julia>@dynamic_import modules#符号
最后,您可以将其全部包装到一个文件中,以便使用DynamicImport使用

注意:当前,我在尝试从模块运行相同示例时得到以下信息:

julia>使用DynamicImport
朱莉娅>@dynamic_import[:mod01,:mod02]
julia>rx=r“^mod[0-9][0-9].jl$”;
julia>@需要动态\u导入\u模块(rx)
错误:未定义接收
julia>模块=需要的模块(rx)
二元数组{符号,1}:
:mod01
:mod02
julia>@动态导入模块
错误:未定义模块

但是,如果我在REPL中定义对象,它可以正常工作,我想这是一个涉及卫生的问题,这是我没有经验的,所以我会在julia用户邮件列表中询问。

因为
import
是一个关键字,而不是一个函数,我想说你需要为此定义一个。@Jubobs我曾经尝试过通过宏来实现这一点,但是Julia似乎不喜欢宏中的
import
语句。关于
import X
require(“X”)
之间等价性的文档是否存在?<代码>包含 VS >代码>导入< /COD> VS <代码>使用是我所遇到的更令人困惑的方面之一。如果您发现此文档不足以帮助您,请考虑打开一个问题或编辑文档本身。(在GitHub上的web浏览器中打开相关文件,然后单击小铅笔图标)@tholy我看到了
require
文档,也查看了模块部分,但不清楚
import
是否只是在
require
上添加了一些语法糖,或者调用其中一个是否有额外的副作用。在谷歌群组上,以赛亚建议
eval(Expr(:import,symbol(modn)))
,它显式地调用了
导入
。我还知道最近关于julia user滥用
包含(),但如果能有一个faq,明确列出何时使用
require
vs
include
vs
import
以及为什么,无论是在包含模块还是不包含模块的文件的上下文中,那就太好了。