用 Python 调用 NetLogo
在上期笔记中介绍了如何在 Java 中调用 NetLogo,本篇博客介绍如何在 Python 中调用 NetLogo。实现依赖一个 Python 包 PyNetLogo,而 PyNetLogo 依赖 JPype,以实现在 Python 中调用 Java。完整的调用逻辑如下
由上图可知,本质上 PyNetLogo 需要调用 NetLogo API 来启动 NetLogo 模型和交换数据。下面介绍 PyNetLogo 的安装和简单使用,对于高阶用法,如借助 pandas 在 Python 和 NetLogo 间交换数据,请查看官方文档。
首先安装 PyNetLogo 及所依赖的 JPype,
pip install JPype1 pynetlogo
下面的代码展示了 PyNetLogo 定义的核心类 NetLogoLink 的使用。可以看到,其提供的接口与 NetLogo API 基本一致。
import pyNetLogo
def test():
netlogo = pyNetLogo.NetLogoLink(
netlogo_home='/home/rotopia/Downloads/NetLogo-6.2.1/',
netlogo_version='6.2',
# jvmargs: ['-Dkey=value', ...]
# jvmargs=['-Djava.library.path=/home/rotopia/R/x86_64-pc-linux-gnu-library/4.1/rJava/jri'],
)
netlogo.load_model('../netlogo/model.nlogo')
netlogo.command('setup')
netlogo.command('repeat 1 [ go ]')
netlogo.kill_workspace()
if __name__ == '__main__':
test()
有两个地方值得注意:
- NetLogo 的版本
官方文档称 PyNetLogo 在 5.2 及以上的版本上测试通过。查看其核心代码 core.py
发现,该库实际上支持 5.0 及以上的版本,截取部分代码如下
# Jar supports NetLogo 5.x, 6.0, or 6.1
jar_name = {'5': 'netlogolink53.jar',
'6.0': 'netlogolink60.jar',
'6.1': 'netlogolink61.jar',
'6.2': 'netlogolink61.jar'}
需要注意的是,在 NetLogo 5.3 之后,extensions 的路径从 ./extensions
变成了 ./app/extensions
,而 core.py
是为 5.3 及以上的版本写的,因此在使用较低版本的 5.1 和 5.2 时,需要修改 core.py
中 extensions 的路径,截取代码如下
# enable extensions
if sys.platform == 'darwin':
exts = os.path.join(netlogo_home, 'extensions')
elif sys.platform == 'win32':
exts = os.path.join(netlogo_home, 'app', 'extensions')
else:
# modified: for NetLogo 5.1 and 5.2
exts = os.path.join(netlogo_home, 'extensions')
# original: for NetLogo 5.3 and above
# exts = os.path.join(netlogo_home, 'app', 'extensions')
- 传递 Java 虚拟机的参数
NetLogoLink 类贴心地提供了传递 Java 虚拟机的参数的接口,只需在参数列表jvmargs
中指定,格式为'-Dkey=value'
。