如何从Python捕获Matlab函数的输出

3 投票
1 回答
1617 浏览
提问于 2025-04-18 15:26

我正在运行下面的Python代码,它用来计算一个数组的平均值:

def matlab_func1(array):
    p = os.popen('matlab -nodesktop -nosplash  -r "mean('+str(array)+');exit"')
    while 1:
        line = p.readline()
        if not line:
            break
        print line

matlab_func1([1,2,3]) 

从下面的Matlab脚本可以看到,输出结果返回给了y。我想从Python中获取这个输出。

function y = mean(x,dim)
...
...
end

这个解决方案必须适用于其他的Matlab函数。'mean'函数只是一个例子。

1 个回答

1

使用 fprintf 可以把需要的文本写入 stderr。只需在开头加一个额外的参数 2

import subprocess
import os
def matlab_func1(array):
    p = subprocess.Popen(['/home/user/Matlab/bin/matlab', '-nodesktop', '-nosplash', '-r "m = mean(' + str(array) + ');fprintf(2, \'%d\\n\',m);exit" >/dev/null'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    while 1:
        try:
            out, err = p.communicate()
        except ValueError:
            break
        print 'hello' + err

matlab_func1('[1,2,3]') 

需要注意几点:

  • 把 Python 的命令改成 subprocess.Popen,这样可以处理 stderr 的输出。
  • 在 Matlab 的命令中,使用 fprintf 把想要的信息写入 stderr。这样可以把代码输出和 Matlab 的头部信息分开。
  • 回到 Python 中,使用 Popen.communicate() 来获取 stderr 的输出。
  • 异常 ValueError 用来处理 Matlab 的退出事件(p 被关闭)。

编辑:

对于一个返回多个输出的函数

假设一个 Matlab 函数是

function [y, z] = foo(x)
    y = x+1;
    z = x*20;
end

关键是使用 fprintf 来输出结果,同时在 Matlab 中做其他事情时,和往常一样。

方法 1 - 内联脚本

p = subprocess.Popen(['/home/user/Matlab/bin/matlab', '-nodesktop', '-nosplash', '-r "[y, z] = foo(' + str(array) + ');for ii=1:length(y) fprintf(2, \'%d %d\\n\',y(ii),z(ii)); end; exit" >/dev/null'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

方法 2 - 独立脚本

首先创建一个新的 caller.m 脚本

[y, z] = foo(x);
for ii=1:length(y)
    fprintf(2, '%d %d\n',y(ii),z(ii));
end

注意在从 Python 调用时要给 x 赋值;脚本共享同一个堆栈。(记得不要在调用脚本中 clear 工作区。)

然后,从 Python 调用这个脚本

p = subprocess.Popen(['/home/user/Matlab/bin/matlab', '-nodesktop', '-nosplash', '-r "x=' + str(array) + ';caller; exit" >/dev/null'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

把 Matlab 结果存储在 Python 变量中

  • 当通过 stdout / stderr 管道传递数据时:

    可以参考 这个subprocess.check_output()

  • 当处理像 double 或二进制这样的复杂数据时:

    先用 Matlab 把数据写入一个外部文件。然后用 Python 读取这个文件。需要定义一个协议,让双方能够互相沟通。

撰写回答