跳转到内容

介绍 Julia/模块和包

来自 Wikibooks,开放世界中的开放书籍
Previous page
元编程
介绍 Julia Next page
DataFrames
模块和包

模块和包

[编辑 | 编辑源代码]

Julia 代码被组织成文件、模块和包。包含 Julia 代码的文件使用 .jl 文件扩展名。

相关的函数和其他定义可以分组在一起并存储在模块中。模块的结构如下所示

module MyModule
 
end

在这些行之间,您可以放置函数、类型定义、常量等等。

一个或多个模块可以存储在一个中,这些包使用 git 版本控制系统进行管理。大多数 Julia 包,包括官方包,都存储在 GitHub 上,按照惯例,每个 Julia 包都以“.jl”后缀命名。

安装模块

[编辑 | 编辑源代码]

要在您自己的机器上使用官方(注册)的 Julia 模块,您需要从主 GitHub 网站下载并安装包含该模块的包。所有正式注册的包列表可以在 GitHub 上的Julia General Registry中找到,但使用 JuliaHubJulia Packages 网站搜索包更方便。

要下载并安装包,您可以使用 Julia 的包管理器 Pkg。首先在 REPL 中输入右括号 ] 进入包管理器,然后使用 add 命令。您不需要使用引号或“.jl”后缀。

julia> ]
(v1.0) pkg> add Calculus
... messages
(v1.0) pkg>

(如果您没有直接连接到互联网,您需要在调用包安装程序之前提供代理的名称。)

提示中的(v1.0)表示您正在使用默认项目“v1.0”,位于 ~/.julia/environments/。每次发布都会有一个新的默认项目,因此在 2022 年,您可能会看到 v1.7 或 v1.8 作为默认项目。(项目是定义 Julia 环境的典型方法,也是最常见的方法,环境是一组包,这些包共同定义了 Julia 代码的加载和运行方式。)

如果您想更新已有的包,请使用 up 命令

(v1.0) pkg> up
... messages
(v1.0) pkg>

有关 Julia 功能强大的包管理系统的更多信息,请参阅完整的文档

要退出包管理器模式,请按退格键/删除键。

使用模块/包

[编辑 | 编辑源代码]

安装后,要开始使用包中的函数和定义,您可以告诉 Julia 将代码提供给您当前的会话,使用 usingimport 语句,这些语句接受一个或多个已安装模块的名称

julia> using Calculus

julia>

成功后,Calculus 包中的所有定义都可供使用。如果 Calculus 模块内部的定义由作者导出,您可以在没有模块名称作为前缀的情况下使用它们(因为我们使用了 using

julia> derivative(sin, pi/2)
0.0

如果作者没有导出定义,或者我们使用 import 而不是 using,您仍然可以访问它们,但必须输入模块名称作为前缀

julia> Calculus.derivative(sin, pi/2)
0.0

但在这个特定示例中,这是不必要的,正如我们所见。

因此,当您编写自己的模块时,您选择导出的函数可以在没有模块名称作为前缀的情况下使用。您没有导出的函数仍然可以使用,但前提是它们必须加上模块名称作为前缀。例如,在名为 MyCoolModule 的模块中,mycoolfunction() 被导出。因此,前缀是可选的

julia> using MyCoolModule

julia> MyCoolModule.mycoolfunction()
"this is my cool function"

julia> mycoolfunction()
"this is my cool function"

在模块内部,此函数使用 export 语句导出

module MyCoolModule
export mycoolfunction

function mycoolfunction()
   println("this is my cool function")
end

end

using 和 import

[编辑 | 编辑源代码]

importusing 类似,但在某些方面有所不同,例如在如何访问模块内部的函数方面。这是一个包含两个函数的模块,其中一个函数被导出

module MyModule
export mycoolfunction

function mycoolfunction()
   println("this is my cool function")
end

function mysecretfunction()
   println("this is my secret function")
end

end

使用 import 导入模块

julia> import MyModule

julia> mycoolfunction()
ERROR: mycoolfunction not defined

julia> MyModule.mycoolfunction()
"this is my cool function"

请注意,mycoolfunction() 只能在您使用模块前缀时访问。这是因为 MyModule 模块是使用 import 而不是 using 加载的。类似地,对于 mysecretfunction() 也是如此

julia> mysecretfunction()
ERROR: mysecretfunction not defined

julia> MyModule.mysecretfunction()
this is my secret function

您可以指定一组模块

julia> using Color, Calculus, Cairo

另一个重要区别是,当您想要修改或扩展另一个模块中的函数时。您不能使用 using,必须 import 特定的函数。

如果您想使用其他文件中不包含在模块中的代码,请使用 include() 函数。这会在当前模块的上下文中评估文件的内容,相对于调用它的源文件路径进行搜索。就像您只是粘贴了代码一样。这对于从多个较小的文件中构建代码很有用。

Julia 如何找到一个模块?

[编辑 | 编辑源代码]

Julia 会在 LOAD_PATH 变量中定义的目录中查找模块文件。

julia> LOAD_PATH
3-element Array{String,1}:
 "@"      
 "@v#.#"  
 "@stdlib"

要让它在其他地方查找,请使用 push! 添加更多内容

julia> push!(LOAD_PATH, "/Users/me/myjuliaprojects")
3-element Array{String,1}:
 "@"      
 "@v#.#"  
 "@stdlib"                                                     
 "/Users/me/myjuliaprojects"      

并且,因为您不想每次运行 Julia 时都这样做,请将此行放在您的启动文件 ~/.julia/config/startup.jl 中,它会在您启动交互式 Julia 会话时每次运行。

Julia 会在这些目录中查找结构为包的文件

ModuleName/src/file.jl

或者,如果不在包形式中(见下文),它会查找与您的模块名称匹配的文件名

julia> using MyModule

这将查看 LOAD_PATH 中是否存在名为 MyModule.jl 的文件并加载该文件中包含的模块。

要查看您当前项目中安装的所有包

julia> ]
(v1.0) pkg> status
   Status `~/.julia/environments/v1.0/Project.toml`
 [c7932e45] AstroLib v0.3.0
 [9e28174c] BinDeps v0.8.8
 [159f3aea] Cairo v0.5.2
 [49dc2e85] Calculus v0.4.0
 [3da002f7] ColorTypes v0.6.7
 [5ae59095] Colors v0.8.2
 [861a8166] Combinatorics v0.6.0
 [34da2185] Compat v0.68.0
 [864edb3b] DataStructures v0.8.3
 [5789e2e9] FileIO v0.9.0
 [53c48c17] FixedPointNumbers v0.4.6
 [28b8d3ca] GR v0.31.0
 [a2bd30eb] Graphics v0.3.0
 [9fb69e20] Hiccup v0.2.1
 [a4bce56a] Iterators v0.3.1
 [e5e0dc1b] Juno v0.4.1
 ... messages 
 ...
(v1.0) pkg> 

包的结构

[编辑 | 编辑源代码]

Julia 使用git 来组织和控制包。按照惯例,所有包都存储在 git 存储库中,以“.jl”为后缀。因此,Calculus 包存储在名为 Calculus.jl 的 Git 存储库中。以下是 Calculus 包在磁盘上的文件组织方式

Calculus.jl/                                       # this is the main package directory for the Calculus package
  src/                                             # this is the subdirectory containing the source
    Calculus.jl                                    # this is the main file - notice the capital letter
      module Calculus                              # inside this file, declare the module name
        import Base.ctranspose                     # and import other packages
        export derivative, check_gradient,         # export some of the functions defined in this package
        ...
        include("derivative.jl")                   # include the contents of other files in the module
        include("check_derivative.jl")             
        include("integrate.jl")
      end                                          # end of Calculus.jl file
    derivative.jl                                  # this file contains code for working with derivatives, 
      function derivative()                        #      and is included by Calculus.jl
        ...
      end
        ...
    check_derivative.jl                            # this file concentrates on derivatives, 
      function check_derivative(f::...)            #      and is included by "include("check_derivative.jl")" in Calculus.jl
        ...
      end
      ...
    integrate.jl                                   # this file concentrates on integration, 
      function adaptive_simpsons_inner(f::Funct   # and is included by Calculus.jl
        ...
      end
      ...
    symbolic.jl                                    # concentrates on symbolic matters; included by Calculus.jl
      export processExpr, BasicVariable, ...       # these functions are available to users of the module
      import Base.show, ...                        # some Base functions are imported, 
      type BasicVariable <: AbstractVariable       # ... so that more methods can be added to them
        ...
      end
      function process(x::Expr)
        ...
      end
      ...     
  test/                                            # this directory contains the tests for the Calculus module
    runtests.jl                                    # this file runs the tests
      using Calculus                               # obviously the tests use the Calculus module... 
      using Base.Test                              # and the Base.Test module... 
      tests = ["finite_difference", ...            # the test file names are stored as strings... 
      for t in tests
        include("$(t).jl")                         # ... so that they can be evaluated in a loop 
      end
      ...
    finite_difference.jl                           # this file contains tests for finite differences, 
      @test ...                                    # ... its name is included and run by runtests.jl
      ...

标准库

[编辑 | 编辑源代码]

Base 和 Core 模块始终在 Julia 中可用。有一组标准(或stdlib)模块与 Julia 一起安装,但并非所有模块都在 Julia 会话开始时加载。

如果 stdlib 模块尚未加载,请以通常的方式使用 usingimport 加载它们。

Julia 1.7 版本包含以下包

Base64 编码和解码 Base64 字符串
CRC32c 计算 CRC-32c 校验和
Dates 处理日期和时间
DelimitedFiles readdlm() 和 writedlm() 函数用于读取和写入分隔符分隔的文本数据
Distributed 在集群中的多台机器上工作
Downloads 下载文件
FileWatching 监视文件和目录的变化
Future 实现未来版本的已有函数,这些函数将在未来版本中替换当前版本
InteractiveUtils 帮助和内省函数(通常与 REPL 一起加载)
Libdl 动态链接器
LibGit2 与 Git 库的绑定
LinearAlgebra 线性代数函数
Logging 记录计算的历史记录和进度
Markdown 支持 Markdown 文本格式约定
Mmap 处理内存映射数组
Pkg 管理包的安装
Printf C 样式的 printf 格式化
Profile 用于分析性能的工具
Random 随机数生成
REPL Julia 的交互式命令行 REPL
序列化 写入和读取 Julia 数据
SHA 提供对安全哈希算法 (SHA) 的支持
共享数组 共享数组
套接字 TCP 套接字支持
稀疏数组 与密集数组相比节省空间的数组
统计 基本统计函数:stdcorvarcovmeanmedianquantile
SuiteSparse
TOML 解析 TOML 文件
测试 测试工具
Unicode 一些 Unicode 工具
UUID 生成全局唯一标识符
华夏公益教科书