在使用 DolphinDB 的脚本进行开发时,可以创建可复用模块,以封装自定义函数。模块可以将大量函数按目录树结构组织在不同模块中。既可以在系统初始化时预加载模块,也可以在需要使用的时候引入模块。
在 DolphinDB 中,模块是只包含函数定义的脚本文件。它具有以下特点:
所有的模块定义默认存放在 [home]/modules 目录下:
在 modules 目录下创建以 .dos 为后缀的模块文件,例如 fileLog.dos。模块文件的第一行必须是模块声明语句。例如在 fileLog.dos 中声明模块:
module fileLog
其中 fileLog 是模块名,必须与模块文件(fileLog.dos)的名称一致。
模块文件除第一行外的内容仅可包含函数定义或模块导入语句(如需引用其它模块)。例如,fileLog 模块仅包括向指定日志文件写入日志的函数 appendLog
:
module fileLog
def appendLog(filePath, logText){
f = file(filePath,"a+")
f.writeLine(string(now()) + " : " + logText)
f.close()
}
在模块文件中,除函数定义、模块声明语句和模块导入语句外,其它代码将被忽略。
使用 saveModule 函数可以将模块序列化成扩展名为 dom 的二进制文件。将模块序列化为 dom 文件能够增强代码的保密性和安全性。例如,序列化2.2中的 module fileLog:
saveModule("fileLog")
dom 文件会保存至 dos 文件所在的目录。
注意:
如果 dos 文件的内容发生改变,需要重新执行 saveModule 函数来生成新的 dom 文件。可将 saveModule 函数的 overwrite 参数设置为 true 来覆盖已有的 dom 文件。例如:
saveModule("fileLog" , , true)
如果当前模块引用了另一个模块的函数,则在序列化该模块中只会对其依赖模块的名称进行序列化,不会序列化依赖函数的定义。因此,在加载或移动 .dom 文件时,需同时加载或移动其依赖的模块文件。
使用 use
关键字来导入一个模块。如果导入的模块依赖了其他模块,系统会自动加载其他模块。
注意:
use
关键字导入的模块是会话隔离的,仅对当前会话有效。use
关键字仅可导入后缀为 .dos 的模块文件,不可导入 .dom 二进制文件。导入模块后,可以通过以下两种方式来使用模块内的自定义函数:
(1) 直接使用模块中的函数:
use fileLog
appendLog("mylog.txt", "test my log")
(2) 指定模块中的函数的命名空间(即在 modules 目录下的完整路径):
use fileLog
fileLog::appendLog("mylog.txt", "test my log")
若导入的不同模块中含有相同名称的函数,则必须通过此种方式调用此类函数。
该功能在1.20.1及以上版本支持。
3.1节提到,use
关键字导入的模块是会话隔离的,这在实际使用中会带来一些不便。为了解决这一问题,DolphinDB 支持通过 loadModule 函数或者配置参数 preloadModules 将模块定义的函数加载为系统的内置函数,这样模块对所有会话都是可见的。
模块定义的函数成为内置函数之后,具有以下特点:
use
关键字导入模块,使得调用模块的代码更加简洁,API 调用模块函数更加方便。可以通过 .dos 文件或 .dom 文件加载模块。系统会自动到 modules 目录寻找模块文件。如果目录中包含同名的 .dos 文件和 .dom 文件,系统只加载 .dom 文件。如果加载的是 .dom 文件,则用户无法查看模块内函数的定义。
如果加载的模块中引用了其他模块:
该函数只能在系统的初始化脚本(默认是dolphindb.dos)中使用,不能在命令行或者 GUI 中执行。例如,加载2.2中的模块 fileLog,在 dolphindb.dos 文件末尾加上:
loadModule("fileLog")
通过此方法加载模块后,在调用模块函数时必须指定函数的命名空间(即在 modules 目录下的完整路径):
fileLog::appendLog("mylog.txt", "test my log")
对单机版,该参数在 dolphindb.cfg 中配置。对集群版,需要为 controller 和 datanode 加载相同的模块。最简单的方法在 controller.cfg 和 cluster.cfg 中配置 preloadModules 参数。
例如:
preloadModules=fileLog
如果需要加载多个模块,使用逗号分隔。模块函数加载方法同 loadModule
通过 loadModule 或 preloadModules 生成的内置函数与 function view 对比,有以下区别:
function view 和模块的应用场景有所不同。function view 一般用于跟数据库相关的数据访问。模块中的函数一般是通用的处理逻辑或算法。function view 可能会调用模块中的函数,但是模块中的函数一般不调用 function view。
如果需要对模块进行分类,可在 modules 目录下设置多个子目录,以作为不同模块类别的命名空间。例如,现有两个模块 fileLog 和 dateUtil,它们分别存放于 modules/system/log/fileLog.dos 与 modules/system/temperal/dateUtil.dos。这两个模块相应的声明语句分别为 module system::log::fileLog
与 module system::temperal::dateUtil
。
在对模块进行序列化(saveModule)、通过 use
语句导入、以及通过 loadModule 函数或 preloadModules 配置参数加载时,均需指定完整路径。例如,导入上一节中的 fileLog 模块:
use system::log::fileLog
可以通过以下两种方法调用模块函数:
appendLog("mylog.txt", "test my log")
system::log::fileLog::appendLog("mylog.txt", "test my log")
当 GUI 所在机器与 DolphinDB 服务器不是同一台机器时,在 GUI 中编辑的模块代码,需要先上传到远程服务器的 [home]/modules 目录,才能通过 use
语句调用模块。其中[home]表示DolphinDB 的主目录,通过配置项 home 指定。
DolphinDB GUI 从0.99.2版本开始提供了远程同步模块的功能,具体用法如下:
指定远程服务器路径:
添加远程服务器(Server->Add Server)时,指定 Remote Directory
目录:
若上步中未指定 Remote Directory
,可通过 Server->Edit Server 进行添加:
点击下图 Synchronize to server
将 modules 目录下的所有文件和子目录同步到步骤1设置的 Remote Directory
下。
假设 Remote Directory
设置为'[home]/modules',本地需要同步的文件名是 "C:/users/usr1/Project/scripts/test.dos"。同步的时候,系统会在远端自动创建目录和相应文件 '[home]/modules/Project/scripts/test.dos'。
同步完成后,就可以在远程服务器上执行 use
语句导入模块。需要注意的是,在使用模块前,需要参考2.1 节设置模块路径。
不同模块中可以定义相同名字的函数。如果使用全路径调用函数,可以通过模块命名空间来区分函数。
如果直接调用函数:
Modules [Module1] and [Module2] contain function [functionName]. Please use module name to qualify the function.
下例中,首先创建自定义函数myfunc
:
login("admin","123456")
def myfunc(){
return 1
}
addFunctionView(myfunc)
然后定义模块sys,其中含有函数myfunc
。
module sys
def myfunc(){
return 3
}
若要调用模块sys中的函数myfunc
,可在使用
use sys
之后,使用:
sys::myfunc()
或:
myfunc()
若要使用模块外的自定义函数,可使用:
::myfunc()
通过 use
导入模块时,模块函数被加载到缓存中,后续调用函数时,都将从缓存中进行调用。若需要在测试过程中快速反复修改模块代码并刷新定义,可采用以下方法:
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。