2016-10-22 4 views
0

Ich habe einen Python-Code, der eine Matlab-Funktion sussum (a, nx, ny) im Hintergrund mit subprocess.Popen ausführt. Ich kann es nicht funktionieren. Weil ich die Eingabeargumente nicht korrekt an Matlab übergeben kann. Hier ist der Python-Code:Aufrufen einer Matlab-Funktion mit Python Subprozess.Popen

#!/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() 

das Python-Skript ausführt, in dem Befehlsanschluss eines Cluster-Netzwerk, bis er die Fehlermeldung ausspuckt: Undefiniert Funktion oder Variable ‚a‘.

Ich bin sicher, dass die Matlab-Funktion Sussum (a, nx, ny) funktioniert gut, weil ich getestet habe es Python-API Matlab als matlab.engine.start_matlab() verwenden. Sussum (a, nx, ny) und gab die gewünschten Ergebnisse. Jede Hilfe beim Ausführen des Python-Codes mit subprocess.Popen() wird sehr geschätzt.

+1

Sie übergeben die Werte Ihrer Variablen nicht an die Funktion, Sie schreiben effektiv die Zeichenfolge "sussum (a, nx, ny)" als Parameter für die Shell, wenn Sie Popen aufrufen. Das gleiche, als ob Sie Ihr lmb-Wort in die Shell eingegeben hätten, es hat keine Ahnung von dem Wert dieser Variablen. Sie müssen sie aus den numpy-Matrizen in die Matlab-Syntax übersetzen, um die Werte anstelle der Namen der Variablen zu übergeben, wenn Sie die Funktion auf diese Weise aufrufen möchten. – TWReever

+0

@TWReaver: Sie sollten das als Antwort verwenden – TheBlackCat

Antwort

1

Wenn Sie subprocess.Popen(args) verwenden, um ein Popen Objekt zu erstellen, verwenden Sie es effektiv, um den Inhalt Ihrer lmb Liste (mit Leerzeichen verbunden) an die auszuführende Shell zu übergeben. In diesem Fall wäre das Äquivalent des Befehls sein:

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

Offensichtlich ist dies einen Fehler verursachen würde, wenn Sie es direkt von der Shell lief, weil die von diesem Befehl erstellt MATLAB Beispiel nicht, dass die a nicht kennt, nx und sind Variablen, und die Shell behandelt das Ganze nur als String, den sie in diesem Fall als Argument an den Parameter -r übergibt. Wenn Sie dies über die Befehlszeile ausführen, müssen Sie diese Symbole durch Werte ersetzen, die etwas bedeuten, wenn sie an MATLAB übergeben werden. Sie können dies tun, indem Sie entweder die Variablen manuell in den Befehl selbst schreiben oder die geeignete Methode der Variablenerweiterung für die von Ihnen verwendete Shell verwenden.

Wenn Sie versuchen, es durch ein Python Popen Objekt auszuführen, müssen Sie die Variablen in die tatsächliche fun Zeichenfolge ersetzen. Wenn Sie diese streng in Python zu tun, so könnte man so etwas wie

# 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)) 

Leider tun, da Sie ziehen Ihre a, nx und ny Werte aus einer numpy.ndarray, die Sie von scipy.io.loadmat Sie haben etwas mehr Arbeit vor dir, um die Werte von dort zu extrahieren und sie in ein Format zu formatieren, das für die Funktion sussum annehmbar ist.

Verwandte Themen