Julia机器学习核心编程:人人可用的高性能科学计算
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.8 包管理

Julia提供了一个内置的包管理器——Pkg。我们可以使用Pkg来安装用Julia编写的包,但对于未注册的包,则无法直接用Pkg安装。可以在http://pkg.julialang.org上查看到已注册的包列表。在安装Julia时,Pkg包管理器已经被默认安装,所以可以直接使用。

Pkg有很多命令,接下来我们会逐一介绍这些命令的具体用法和注意事项。

1.8.1 使用Pkg.status()显示所有已安装的包

Pkg.status()命令的作用是以列表形式打印所有已安装的包,如图1-29所示。

图1-29 使用Pkg.status()显示已安装的包

如果不知道自己都安装了哪些包,或者不清楚自己所需要的包是否已安装,就可以使用这个命令来快速查看。在Pkg命令首次运行时,它会自动创建一个包目录,Pkg.status()命令会从该目录中查找并返回已安装的包列表,并显示包的版本。

使用Pkg.installed()也可以达到同样的效果,区别在于呈现信息的方式不同,具体如范例1-3所示。

【范例1-3】使用Pkg.installed()显示已安装的包

01  julia> Pkg.installed()
02  Dict{String,Union{Nothing, VersionNumber}} with 10 entries:
03    "Juno"          => v"0.5.3"
04    "Vega"          => v"0.8.0"
05    "KernelDensity" => v"0.5.1"
06    "IJulia"        => v"1.13.0"
07    "Distributions" => v"0.16.4"
08    "RDatasets"     => v"0.6.1"
09    "PyPlot"        => v"2.6.3"
10    "Atom"          => v"0.7.10"
11    "UnicodePlots"  => v"0.3.1"
12    "Gadfly"        => v"1.0.0"

代码01行执行Pkg.installed()命令,02~12行均为该命令的输出结果,可以看到和Pkg.status()的输出结果相同,只不过显示方式不一样。

1.8.2 使用Pkg.add()添加包

Julia的包管理器非常智能,只需告诉它包名,就会自动选择安装哪个版本的包,并解决和其他包之间的依赖关系。我们可以使用Pkg.add (packagename)来添加包。

比如这里想要安装RDatasests包,可以在终端输入如图1-30所示的命令,这样RDatasets包就会存在于已下载的包列表中。

图1-30 添加RDatasets包

或者通过手工编辑需求列表,来确定我们所需要的包及其版本。在~/.julia/v0.5/REQUIRE文件中记录了包需求列表,我们可以使用vim或Atom等文本编辑器打开它,或者使用Pkg.edit()在Julia中对它进行编辑。编辑文件后,运行Pkg.resolve()来安装或删除对应的包。

如果有一天我们不想再使用RDatasets包了,就可以使用Pkg.rm()将它从REQUIRE文件中删除,如图1-31所示。

图1-31 删除RDatasets包

与Pkg.add()类似,Pkg.rm()首先从REQUIRE文件中删除包,然后通过运行Pkg.resolve()来匹配已更新的安装包列表。如果一次只安装一个包,那么使用Pkg.add()和Pkg.rm()十分方便。但如果在服务器上配置生产环境时需要一次性添加或删除多个包,这时就可以调用Pkg.edit()来手动更改REQUIRE文件的内容,然后更新包。如果Pkg.resolve()运行失败;则Pkg.edit()不会回滚REQUIRE文件的内容。在这种情况下,只能再次运行Pkg.edit()来手工修复文件的内容。

1.8.3 安装未注册包

除了Pkg中含有的包,通常我们还希望使用团队成员创建的包,或者在GitHub上发布但尚未在Pkg中的注册包,Julia允许我们使用GitHub Clone来实现。

如果Julia包被托管在GitHub存储库中,那么可以使用Git对包进行克隆。对于Julia来说,已注册包的索引被保存在METADATA.jl中。对于非官方的包,我们可以使用以下命令来添加:

julia> Pkg.clone
("git://github.com/path/unofficialPackage/Package.jl.git")

Julia包的名称以.jl结尾,这可以有效地防止Julia和其他语言中具有相同名称的包发生命名冲突,也让搜索Julia包变得更加容易。有时候,未注册包对其他包具有一定的依赖性。不过不用担心,在运行Pkg.clone(url)时,Julia会自动安装这些依赖项,不再需要另外安装。

这里的unofficialPackage指的是未注册包的名称。只有未注册包被托管在GitHub上时才能使用上面这条命令,并且在使用时要替换“path/unofficialPackage”的路径为实际路径。

1.8.4 使用Pkg.update()更新包

有了Pkg.update(),就不需要频繁地安装和移除包了,并且能第一时间使用最新的包,来保证编写代码的质量。相对于其他语言,Julia还属于比较新的语言,所以Julia语言正在积极开发改进中,相关包还不稳定,有可能该Julia版本能用的包,在下一个版本中就无法使用了,所以包的及时更新显得更加重要。如果想要一次性更新所有的包,则在Julia中输入命令:

Pkg.update()

新的更改会被自动拉入METADATA文件中,并且它可以对任何可能出现的新的注册包版本进行检查。如果有新的注册包版本,Pkg.update()会尝试更新这个包并在分支上标出。如果不想让它自动更新,而是使用特定某一版本的包,那么可以在REQUIRE文件中定义具体的包的版本。

1.8.5 METADATA

如果不想使用官方METADATA.jl下载并安装已注册包,那么还可以通过下面的命令选择不同的METADATA存储库位置:

01  julia> Pkg.init("https://julia.customrepo.com/METADATA.jl.git",
02  "branch")

1.8.6 开发包

Julia允许我们查看源代码,并且可以在GitHub上获得所有已安装包的完整开发记录。如果你有GitHub账号,则可以更改Julia 包的源代码并提交到官方的存储库中,在通过包管理者的审查之后,就可以将自己的代码合并到正式版中。如果你想创建自己的包并在某个时间点发布它们,Julia的包管理器可以满足你的需求,前提是你的系统中已经安装GitHub,并且可以通过SSH连接它。

1.8.7 创建一个新的包

如果你想创建一个新包,则最好在包中包含REQUIRE文件,并且至少应该有对Julia版本的描述。例如,创建一个名为“HelloWorld”的新Julia包,那么可以使用下面的命令生成它:

Pkg.generate("HelloWorld", "MIT")

HelloWorld是新包的名字,MIT是该包将拥有的开源许可证。有了开源许可证,就可以保证别人合理地使用你的代码。目前Pkg.generate()可以识别MIT、BSD和ASL许可证,但用户可以通过更改LICENCE.md来使用任何许可证。