Julia 查找模块';s路径,使用模块对象
从Julia 查找模块';s路径,使用模块对象,julia,Julia,从模块对象到声明该对象的文件路径的合理方式是什么? 确切地说,我正在查找出现关键字模块的文件 间接方法是在每个模块中查找自动定义的eval方法的位置。 moduleloc(mm::Module)=first(functionloc(mm.eval,(Symbol,))) 比如说 moduleloc(mm::Module) = first(functionloc(mm.eval, (Symbol,))) using DataStructures moduleloc(DataStructures)
模块
对象到声明该对象的文件路径的合理方式是什么?
确切地说,我正在查找出现关键字模块
的文件
间接方法是在每个模块中查找自动定义的eval
方法的位置。
moduleloc(mm::Module)=first(functionloc(mm.eval,(Symbol,)))
比如说
moduleloc(mm::Module) = first(functionloc(mm.eval, (Symbol,)))
using DataStructures
moduleloc(DataStructures)
产出:
/home/oxinabox/.julia/v0.6/DataStructures/src/DataStructures.jl
这种间接的方法是有效的,但感觉有点混乱。
我是否错过了执行此操作的一些内置功能
我会提醒你,模块和包不是一回事。
考虑子模块的存在,或者甚至通过<代码>加载的模块包括 < P>如果您没有寻找编程的方式,可以使用<代码>方法< /代码>函数> < /P>
using DataFrames
locations = methods(DataFrames.readtable).ms
它适用于所有方法,但要找到正确的方法并不困难,除非你有大量的方法,但这些方法的差别很小。
需要
显然需要执行该操作。查看load.jl
,我发现查找模块路径最近有点变化:在中,有一个函数
load_hook(prefix::String, name::String, ::Void)
您可以称之为“手动”:
但是,这一情况在未来几年有所好转,;现在有一个函数find_package
,我们可以复制它:
macro return_if_file(path)
quote
path = $(esc(path))
isfile(path) && return path
end
end
function find_package(name::String)
endswith(name, ".jl") && (name = chop(name, 0, 3))
for dir in [Pkg.dir(); LOAD_PATH]
dir = abspath(dir)
@return_if_file joinpath(dir, "$name.jl")
@return_if_file joinpath(dir, "$name.jl", "src", "$name.jl")
@return_if_file joinpath(dir, name, "src", "$name.jl")
end
return nothing
end
并添加一个小助手:
find_package(m::Module) = find_package(string(module_name(m)))
基本上,这需要Pkg.dir()
并查看“常用位置”
此外,v0.6.0中的chop不接受这些附加参数,我们可以通过添加
chop(s::AbstractString, m, n) = SubString(s, m, endof(s)-n)
此外,如果您不在Unix上,您可能需要关心链接代码上方的isfile\u区分大小写的定义
如果你不太关心角案,也许这就足够了,或者可以作为一个基础:
function modulepath(m::Module)
name = string(module_name(m))
Pkg.dir(name, "src", "$name.jl")
end
编辑:我现在意识到你想要使用模块对象
julia> m = DataStructures
julia> Pkg.dir(repr(m))
"/home/liso/.julia/v0.7/DataStructures"
Edit2:我不确定您是否试图找到模块的路径或模块中定义的对象的路径(我希望从下一个结果解析路径很容易):
模块只是不存储定义它们的文件位置。这一点你自己也可以在书中看到。你唯一的希望就是看看他们的束缚
另一方面,方法确实存储其文件位置。而eval
是每个模块
中定义的一个功能(尽管不是baremodule
s)。稍微正确一点的可能是:
moduleloc(mm::Module) = first(functionloc(mm.eval, (Any,)))
因为这更准确地反映了自动定义的eval方法。我正在寻找一种编程方法。此外,我建议删除.ms
。当结果仍然需要人工检查时,它不会给你带来任何好处。(方法在引擎盖下使用functionloc
,顺便说一句)正如我所说的模块,你第二次是对的。我更新了一个带有类型约束的函数,使问题更清楚。(另外,您的第三个代码也是毫无意义的,repr(它)
调用functionloc
(在我的问题中使用)作为构建该字符串的一部分。为什么我要构建该字符串,然后将其解析出来?)无论如何,基于Pkg.dir
的解决方案只适用于包。不适用于模块。模块=包装。将子模块视为明显不同的情况之一。code>Pkg.dir(repr(TensorFlow.train))=“/home/wheel/oxiabox/.julia/v0.6/TensorFlow.train”
:这是错误的——不存在这样的TensorFlow.train目录。vsmoduleloc(TensorFlow.train)“/home/wheel/oxinabox/.julia/v0.6/TensorFlow/src/train.jl”
这是正确的。您的第一个代码不适用于模块
它适用于包,正如您所标记的那样。当应用于子模块时,考虑:<代码> FIDYORACK包(TunSoReal.Cub)= = No.< /代码>。vsmodulepath(TensorFlow.train)“/home/wheel/oxinabox/.julia/v0.6/TensorFlow/src/train.jl”
?顺便说一句:文件和文件名大多与模块无关;模块仅与模块表达式关联。每个模块可以有多个文件,每个文件可以有多个模块()并定义sane!在您的理解中,mp(m::Module)=ccall(:jl\u gf\u invoke\u lookup,Any,(Any,UInt),Tuple{typeof(m.eval),Symbol},typemax(UInt)).func.file
是正常的吗?我不知道您为什么会发现查看eval
的位置是疯狂的。它在所有模块中自动定义。方法存储它们的路径;我不相信模块有。@Liso每个模块都有一个包含块模块名的文件。。。结束
。是的,我同意,同一个文件中可能有多个模块(但这并不意味着它们不在该文件中),模块内容(但不是声明)可以通过include
分布在多个文件中(甚至一个文件可能是两个模块的内容)。但这是我要找的关键词文件。至于定义疯狂:也许间接是一个更好的词,我会编辑。问题“它是干什么用的?”很重要。因为若有充分的理由,那个么路径可能会被存储。若并没有存储路径,还有什么更直接的方法?如果有可能进行编辑,那么@edit m.eval(“”
不好?如果是为了文档,也许其他方式比内省更明智?我想知道这一点的主要原因是。第二,当模块位于包中时,我将其视为查找相对于该模块的文件的一种选择,例如LISCENSE.md解决方案,因为模块名!=帕卡吉纳姆。一种选择可能是搜索所有模块父级,直到找到倒数第二个模块(可能是包名,尽管我不确定它是否是),然后使用基于包的opt
julia> m = DataStructures
julia> Pkg.dir(repr(m))
"/home/liso/.julia/v0.7/DataStructures"
julia> repr(which(DataStructures.eval, (String,)))
"eval(x) in DataStructures at /home/liso/.julia/v0.7/DataStructures/src/DataStructures.jl:3"
moduleloc(mm::Module) = first(functionloc(mm.eval, (Any,)))