Pergunta

Como eu usaria o módulo de subprocesso no Python para iniciar uma instância da linha de comando do Maple para alimentar e retornar a saída para o código principal? Por exemplo, eu gostaria:

X = '1+1;'
print MAPLE(X)

Para retornar o valor de "2".

O melhor que eu vi é um invólucro sábio em torno dos comandos do Maple, mas eu gostaria de não instalar e usar a sobrecarga do sábio para meus propósitos.

Foi útil?

Solução 2

Usando a dica de Alex Martelli (obrigado!), Recebi uma resposta explícita à minha pergunta. Postando aqui na esperança de que outros possam achar úteis:

import pexpect
MW = "/usr/local/maple12/bin/maple -tu"
X = '1+1;'
child = pexpect.spawn(MW)
child.expect('#--')
child.sendline(X)
child.expect('#--')
out = child.before
out = out[out.find(';')+1:].strip()
out = ''.join(out.split('\r\n'))
print out

A análise da saída é necessária, pois o bordo considera necessário dividir saídas longas em muitas linhas. Essa abordagem tem a vantagem de manter uma conexão aberta ao bordo para a computação futura.

Outras dicas

Tentando impulsionar um subprocesso "interativamente" com mais frequência do que não, está em questões com o subprocesso fazendo alguns buffers, o que bloqueia as coisas.

É por isso que, para tais propósitos, sugiro que use pexpect (em todos os lugares, exceto janelas: wexpect no Windows), que foi projetado exatamente para esse fim - deixando seu programa simular (do ponto de vista do subprocesso) um usuário humano digitando entrada/comandos e analisando os resultados em um terminal/console.

Aqui está um exemplo de como fazer IO interativo com um programa de linha de comando. Eu usei algo semelhante para construir um verificador ortográfico com base no ispell Utilitário de linha de comando:

f = popen2.Popen3("ispell -a")
f.fromchild.readline() #skip the credit line

for word in words:
    f.tochild.write(word+'\n') #send a word to ispell
    f.tochild.flush()

    line = f.fromchild.readline() #get the result line
    f.fromchild.readline() #skip the empty line after the result

    #do something useful with the output:
    status = parse_status(line)
    suggestions = parse_suggestions(line)
    #etc..

O único problema com isso é que é muito quebradiço e um processo de tentativa e erro para garantir que você não esteja enviando nenhuma entrada ruim e lidando com toda a saída diferente que o programa poderia produzir.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top