在 Pluto 中使用本地 Julia 模块
Using local Julia modules in Pluto
使用 Julia 1.7.2 在 Pluto v0.18.0 notebooks 中导入本地模块的正确方法是什么?
using
关键字将导出的成员添加到 Julia 的主命名空间中。给定一个示例模块,在 foo.jl
、
module Foo
export bar
function bar()
return "baz"
end
end
以下代码单元适用于 Pluto Notebook:
# "baz"
begin
include("./foo.jl")
using .Foo
bar()
end
但是,如果我尝试从另一个单元格调用 bar
,我会收到以下错误:
# UndefVarError: bar not defined
bar()
虽然我注意到 Foo.bar()
确实有效。
如何添加我自己的模块,以便我可以直接在笔记本的命名空间中访问它们的导出成员?
这discussion给出了一个可能的解决方案。它描述了一种比我的问题更好的获取模块引用的方法。
如果模块不是文件中的最后一个定义,则必须重新定义import
函数。建议的名称是有一个名为“ingredients
”
的变体
#ingredients (generic function with 1 method)
function ingredients(path::String)
# this is from the Julia source code (evalfile in base/loading.jl)
# but with the modification that it returns the module instead of the last object
name = Symbol(basename(path))
m = Module(name)
Core.eval(m,
Expr(:toplevel,
:(eval(x) = $(Expr(:core, :eval))($name, x)),
:(include(x) = $(Expr(:top, :include))($name, x)),
:(include(mapexpr::Function, x) = $(Expr(:top, :include))(mapexpr, $name, x)),
:(include($path))))
m
end
然后就可以像这样加载模块了(不知道为什么要说ingredients().Foo
)
#Main.Foo.jl.Foo
Foo = ingredients("My Library/Foo.jl").Foo
然后使用模块引用,您必须手动将所有导出的变量放入全局范围:
#bar = bar (generic function with 1 method)
bar = Foo.bar
使用 Julia 1.7.2 在 Pluto v0.18.0 notebooks 中导入本地模块的正确方法是什么?
using
关键字将导出的成员添加到 Julia 的主命名空间中。给定一个示例模块,在 foo.jl
、
module Foo
export bar
function bar()
return "baz"
end
end
以下代码单元适用于 Pluto Notebook:
# "baz"
begin
include("./foo.jl")
using .Foo
bar()
end
但是,如果我尝试从另一个单元格调用 bar
,我会收到以下错误:
# UndefVarError: bar not defined
bar()
虽然我注意到 Foo.bar()
确实有效。
如何添加我自己的模块,以便我可以直接在笔记本的命名空间中访问它们的导出成员?
这discussion给出了一个可能的解决方案。它描述了一种比我的问题更好的获取模块引用的方法。
如果模块不是文件中的最后一个定义,则必须重新定义import
函数。建议的名称是有一个名为“ingredients
”
#ingredients (generic function with 1 method)
function ingredients(path::String)
# this is from the Julia source code (evalfile in base/loading.jl)
# but with the modification that it returns the module instead of the last object
name = Symbol(basename(path))
m = Module(name)
Core.eval(m,
Expr(:toplevel,
:(eval(x) = $(Expr(:core, :eval))($name, x)),
:(include(x) = $(Expr(:top, :include))($name, x)),
:(include(mapexpr::Function, x) = $(Expr(:top, :include))(mapexpr, $name, x)),
:(include($path))))
m
end
然后就可以像这样加载模块了(不知道为什么要说ingredients().Foo
)
#Main.Foo.jl.Foo
Foo = ingredients("My Library/Foo.jl").Foo
然后使用模块引用,您必须手动将所有导出的变量放入全局范围:
#bar = bar (generic function with 1 method)
bar = Foo.bar