【问题标题】:Calling a matlab function with python subprocess.Popen使用 python subprocess.Popen 调用 matlab 函数
【发布时间】:2016-10-22 03:21:44
【问题描述】:

我有一个 python 代码,它使用 subprocess.Popen 在后台运行 matlab 函数 sussum(a,nx,ny)。我无法让它工作。因为我无法正确地将输入参数传递给 matlab。这是python代码:

#!/usr/bin/env python
 import matlab.engine
 import scipy.io as sio
 import numpy as np
 import subprocess as sb
 nproc = 5
 input = sio.loadmat('sus_py.mat')
 totq = input['totq']
 nx,ny = input['nx'],input['ny']
 nq = totq+1
 nx,ny = matlab.int32(nx.tolist()) , matlab.int32(ny.tolist())
 iq = range(1,nq)
 gp = len(iq)/nproc
 list = [iq[j:j+nproc] for j in range(0,len(iq),nproc)]
 for g in range(0,len(list)):
     i = len(list[g])
     p = []
     for n in range(0,i):
         a = matlab.int32(list[g][n])
         fun = '-r "sussum(a,nx,ny); exit" '
         lmb = ['/usr/local/bin/matlab','-nodesktop','-nosplash','-nodisplay','-nojvm',fun]
         p.append(sb.Popen(lmb))
     for q in p:
         q.wait()

python 脚本在集群网络的命令终端中执行,直到它吐出错误消息:未定义的函数或变量'a'。

我确信 matlab 函数 sussum(a,nx,ny) 工作正常,因为我已经使用 Python-Matlab API 作为 matlab.engine.start_matlab().sussum(a,nx,ny) 对其进行了测试,它给出了所需的输出。非常感谢使用 subprocess.Popen() 运行 python 代码的任何帮助。

【问题讨论】:

  • 您没有将变量的值传递给函数,而是在调用 Popen 时有效地将字符串“sussum(a,nx,ny)”作为参数写入 shell。就像您将 lmb 逐字输入 shell 一样,它不知道这些变量的值。如果要以这种方式调用函数,则需要将它们从 numpy 矩阵转换为 Matlab 语法以传递值,而不是变量的名称
  • @TWReever:你应该把它作为答案

标签: python matlab python-2.7 subprocess popen


【解决方案1】:

当您使用subprocess.Popen(args) 创建Popen 对象时,您实际上是在使用它将lmb 列表列表(与空格连接)的内容传递给要执行的shell。在这种情况下,您的命令相当于:

/usr/local/bin/matlab -nodesktop -nosplah -nodisplay -nojvm -r "sussum(a,nx,ny); exit"

显然,如果你直接从 shell 运行它会导致错误,因为这个命令创建的 MATLAB 实例不知道 anxny 是变量,而 shell 只是在这种情况下,将整个事物作为参数传递给-r 参数的字符串。如果您从命令行运行此程序,则需要将这些符号替换为在传递给 MATLAB 时有意义的值。您可以通过在命令本身中手动编写变量来执行此操作,或者为您正在使用的 shell 使用适当的变量扩展方法。

如果您尝试通过 Python Popen 对象运行它,则需要将变量替换为实际的 fun 字符串。如果您在 Python 中严格执行此操作,则可以执行类似

# define variables
a = 10
nx = [1, 2, 3, 4]
ny = [10, 20, 30, 40]

# build fun string from above variables
# -r "sussum(10, [1,2,3,4], [10,20,30,40]); exit;
fun = '-r "sussum({}, [{}], [{}]); exit";'.format(a, ','.join(nx), ','.join(ny))

不幸的是,由于您要从numpy.ndarray 提供的scipy.io.loadmat 中提取您的anxny 值,因此您需要做更多的工作来提取这些值从那里开始并将它们格式化为sussum 函数可接受的格式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 2017-01-14
    • 1970-01-01
    相关资源
    最近更新 更多