---
source_url: https://docs.dolphindb.cn/zh/tutorials/tu_modules.html
fetched_at: 2026-05-19T09:49:53Z
category: tutorials
title: 模块
sha1: b1072d28c63fd68e0e1d3203d6165a5e841615f0
---

# 模块

在使用 DolphinDB
的脚本进行开发时，可以创建可复用模块，以封装自定义函数。模块可以将大量函数按目录树结构组织在不同模块中。既可以在系统初始化时预加载模块，也可以在需要使用的时候引入模块。

## 1. Module（模块）介绍

在 DolphinDB 中，模块是只包含函数定义的脚本文件。它具有以下特点：

- 模块文件默认保存在 [home]/modules 目录下。
- 模块文件名的后缀为 .dos（"DolphinScript"的缩写）或 .dom（"DolphinModule"的缩写）。
- 模块文件第一行只能使用 module 后接模块名以声明模块，即 module module\_name。
- 模块文件除第一行外，仅可包含模块导入语句与函数定义。

## 2. 定义模块

### 2.1. 创建模块目录

所有的模块定义默认存放在 [home]/modules 目录下：

- [home] 目录由系统配置参数 *home* 决定，可以通过 `getHomeDir` 函数查看。
- 节点的模块目录由配置参数 *moduleDir* 来指定，其默认值是相对路径 modules。系统会首先到节点的 home
  目录寻找该目录，如果没有找到，会依次在节点的工作目录与可执行文件所在目录寻找。请注意，单节点模式下，这三个目录默认相同。

### 2.2. 创建模块文件

在 modules 目录下创建以 .dos 为后缀的模块文件，例如 fileLog.dos。模块文件的第一行必须是模块声明语句。例如在 fileLog.dos
中声明模块：

```dolphindb
module fileLog
```

其中 fileLog 是模块名，必须与模块文件（fileLog.dos）的名称一致。

模块文件除第一行外的内容仅可包含函数定义或模块导入语句（如需引用其它模块）。例如，fileLog 模块仅包括向指定日志文件写入日志的函数
`appendLog`：

```dolphindb
module fileLog

def appendLog(filePath, logText){
	f = file(filePath,"a+")
	f.writeLine(string(now()) + " : " + logText)
	f.close()
}
```

在模块文件中，**除函数定义、模块声明语句和模块导入语句外，其它代码将被忽略**。

如果需要对模块进行分类，可在 modules 目录下设置多个子目录，以作为不同模块类别的命名空间。例如，现有两个模块 fileUtil 和
dateUtil，它们分别存放于 modules/system/file/fileUtil.dos 与
modules/system/temporal/dateUtil.dos，那么声明语句分别为 `module
system::file::fileUtil` 与 `module
system::temporal::dateUtil`。

### 2.3. 序列化模块文件

使用 saveModule 函数可以将模块序列化成扩展名为 dom 的二进制文件。将模块序列化为 dom 文件能够增强代码的保密性和安全性。例如，序列化上一节中的
module fileLog：

```dolphindb
saveModule("fileLog")
```

dom 文件会保存至 dos 文件所在的目录。

注意：

- 如果 dos 文件的内容发生改变，需要重新执行 `saveModule` 函数来生成新的 dom 文件。可将
  `saveModule` 函数的 overwrite 参数设置为 true 来覆盖已有的 dom
  文件。例如：

  ```dolphindb
  saveModule("fileLog" , , true)
  ```
- 如果当前模块引用了另一个模块的函数，则在序列化该模块中只会对其依赖模块的名称进行序列化，不会序列化依赖函数的定义。因此，在加载或移动 .dom
  文件时，需同时加载或移动其依赖的模块文件。

## 3. 导入模块

### 3.1. 使用 use 关键字

使用 `use` 关键字来导入一个模块。如果导入的模块依赖了其他模块，系统会自动加载其他模块。

注意：

- `use` 关键字导入的模块是会话隔离的，仅对当前会话有效。
- 自 2.00.12 版本起，use 关键字支持导入后缀为 .dos 的模块文件或 .dom 的二进制文件。

导入模块后，可以通过以下两种方式来使用模块内的自定义函数：

(1) 直接使用模块中的函数：

```dolphindb
use fileLog
appendLog("mylog.txt", "test my log")
```

(2) 指定模块中的函数的命名空间（即在 modules 目录下的完整路径）：

```dolphindb
use fileLog
fileLog::appendLog("mylog.txt", "test my log")
```

若导入的不同模块中含有相同名称的函数，则必须通过此种方式调用此类函数。

### 3.2. 将模块内函数加载为系统内置函数

**注意**：该功能在1.20.1及以上版本支持。

3.1节提到，`use` 关键字导入的模块是会话隔离的，这在实际使用中会带来一些不便。为了解决这一问题，DolphinDB 支持通过
`loadModule` 函数或者配置参数 *preloadModules*
将模块定义的函数加载为系统的内置函数，这样模块对所有会话都是可见的。

模块定义的函数成为内置函数之后，具有以下特点：

- 用户无法覆盖函数的定义。
- 如果在 `remoteRun` 或 `rpc`
  中使用了该函数，系统不会序列化该函数的定义到远程节点。因此远程节点也必须加载该模块，否则系统会抛出无法找到函数的异常。
- 该函数在系统内存中只有一份，且对所有会话可见。不仅节约了内存，还减少了每个会话加载模块的时间。另外，无需使用 `use`
  关键字导入模块，使得调用模块的代码更加简洁，API 调用模块函数更加方便。

可以通过 .dos 文件或 .dom 文件加载模块。系统会自动到 modules 目录寻找模块文件。如果目录中包含同名的 .dos 文件和 .dom
文件，系统优先加载 .dos 文件。如果加载的是 .dom 文件，则用户无法查看模块内函数的定义。

如果加载的模块中引用了其他模块：

- 如果加载的是 .dos 文件，则系统在加载时会自动加载其依赖的模块。
- 如果加载的是 .dom 文件，则必须先加载该模块中所依赖的模块文件。

#### 3.2.1. 通过 loadModule 函数加载

该函数只能在系统的初始化脚本（默认是dolphindb.dos）中使用，不能在命令行或者 GUI 中执行。例如，加载上文“创建模块文件”节中的模块
fileLog，在 dolphindb.dos 文件末尾加上：

```dolphindb
loadModule("fileLog")
```

通过此方法加载模块后，在调用模块函数时必须指定函数的命名空间（即在 modules 目录下的完整路径）：

```dolphindb
fileLog::appendLog("mylog.txt", "test my log")
```

#### 3.2.2. 通过配置参数 preloadModules 加载

对单机版，该参数在 dolphindb.cfg 中配置。对集群版，需要为 controller 和 datanode 加载相同的模块。最简单的方法在
controller.cfg 和 cluster.cfg 中配置 *preloadModules* 参数。

例如：

```dolphindb
preloadModules=fileLog
```

如果需要加载多个模块，使用逗号分隔。

#### 3.2.3. 与函数视图（function view）的区别

通过 `loadModule` 或 *preloadModules* 生成的内置函数与 function view
对比，有以下区别：

- dom 模块中的函数定义对所有人均不可见，包括系统管理员和 owner，保密性更高。function view 的定义对 admin 和
  owner 以及授权用户可见。
- 序列化一个模块时，不会序列化依赖的函数，只会序列化依赖的模块名称。而 function view
  序列化时，会序列化所有的依赖，以及依赖的依赖，实现 self-contained。

function view 和模块的应用场景有所不同。function view
一般用于跟数据库相关的数据访问。模块中的函数一般是通用的处理逻辑或算法。function view 可能会调用模块中的函数，但是模块中的函数一般不调用
function view。

## 4. 模块分类

### 4.1. 声明模块类别命名空间

如果需要对模块进行分类，可在 modules 目录下设置多个子目录，以作为不同模块类别的命名空间。例如，现有两个模块 fileLog 和
dateUtil，它们分别存放于 modules/system/log/fileLog.dos 与
modules/system/temporal/dateUtil.dos。这两个模块相应的声明语句分别为 `module
system::log::fileLog` 与 `module
system::temporal::dateUtil`。

### 4.2. 调用命名空间模块

在对模块进行序列化（saveModule）、通过 `use` 语句导入、以及通过
`loadModule` 函数或 *preloadModules*
配置参数加载时，均需指定完整路径。例如，导入上一节中的 fileLog 模块：

```dolphindb
use system::log::fileLog
```

可以通过以下两种方法调用模块函数：

- 直接调用其中函数：

```dolphindb
appendLog("mylog.txt", "test my log")
```

- 使用全路径调用其中函数：

```dolphindb
system::log::fileLog::appendLog("mylog.txt", "test my log")
```

## 5. GUI中远程调试模块

当 GUI 所在机器与 DolphinDB 服务器不是同一台机器时，在 GUI 中编辑的模块代码，需要先上传到远程服务器的 [home]/modules 目录，才能通过
`use` 语句调用模块。其中[home]表示DolphinDB 的主目录，通过配置项 home 指定。

DolphinDB GUI 从0.99.2版本开始提供了远程同步模块的功能，具体用法如下：

1. 指定远程服务器路径：
   - 添加远程服务器（Server->Add Server）时，指定 `Remote Directory`
     目录:  
     ![image](images/GUI/add_server.png)
   - 若上步中未指定 `Remote Directory`，可通过 Server->Edit Server
     进行添加：  
     ![image](images/GUI/module_sync.png)
2. 点击下图 `Synchronize to server` 将 modules 目录下的所有文件和子目录同步到步骤1设置的
   `Remote Directory` 下。 ![image](images/GUI/module_sync.png)

假设 `Remote Directory` 设置为'[home]/modules'，本地需要同步的文件名是
"C:/users/usr1/Project/scripts/test.dos"。同步的时候，系统会在远端自动创建目录和相应文件
'[home]/modules/Project/scripts/test.dos'。

同步完成后，就可以在远程服务器上执行 `use` 语句导入模块。需要注意的是，在使用模块前，需要参考[上文“创建模块目录”](tu_modules.html#emv_ltk_gcc)设置模块路径。

## 6. 注意事项

### 6.1. 同名函数定义规则

不同模块中可以定义相同名字的函数。如果使用全路径调用函数，可以通过模块命名空间来区分函数。

如果直接调用函数：

- 若只有一个已导入模块包含该函数，DolphinDB 会调用该模块的函数。
- 若多个已导入模块包含该函数，会抛出异常：

  ```dolphindb
  Modules [Module1] and [Module2] contain function [functionName]. 
      Please use module name to qualify the function.
  ```
- 若所有已导入的模块中均不包含该函数，DolphinDB 会在系统内置函数中搜索该函数。如果内置函数中也没有该函数，将抛出函数未定义的异常。
- 若已导入模块中某函数与某自定义函数重名，调用时需要通过命名空间来区分函数。自定义函数和内置函数的默认命名空间为根目录，用两个冒号表示。

下例中，首先创建自定义函数`myfunc`：

```dolphindb
login("admin","123456")
def myfunc(){
 return 1
}
addFunctionView(myfunc)
```

然后定义模块sys，其中含有函数`myfunc`。

```dolphindb
module sys
def myfunc(){
 return 3
}
```

若要调用模块sys中的函数`myfunc`，可在使用

```dolphindb
use sys
```

之后，使用：

```dolphindb
sys::myfunc()
```

或：

```dolphindb
myfunc()
```

若要使用模块外的自定义函数，可使用：

```dolphindb
::myfunc()
```

### 6.2. 刷新模块定义

通过 `use`
导入模块时，模块函数被加载到缓存中，后续调用函数时，都将从缓存中进行调用。若需要在测试过程中快速反复修改模块代码并刷新定义，可采用以下方法：

- 在模块文件修改后执行全部的模块代码。这种方法仅对当前会话有效。
- 调用命令 clearCachedModules，强制清除缓存的模块。当缓存清除后，执行 use 语句时，会重新从文件加载模块，无需重启节点。只有
  admin 才有权限执行这个命令。

### 6.3. 模块间互相调用

- 模块之间可以单向引用，例如允许模块a引用b，b引用c。
- 模块之间不支持交叉引用，例如不允许模块a引用b，模块b又引用a。
