2017-02-23 42 views
1

Мой питон скрипт выглядит так:Ruby: получить возвращаемое значение питона сценария

def main(): 
    ret = [1, 2] 
    return ret 

и я называю сценарий питона из рубина, как это:

output = system("python script.py") 

print output 

Однако значение выхода верно , Я хочу получить [1, 2]. Мой вопрос в том, как я могу получить возвращаемое значение скрипта python?

ответ

1

Сначала попросите свой скрипт Python напечатать значение, а не вернуть его, или добавить print main() внизу, так что будет напечатано возвращаемое значение main().

Во-вторых, на стороне Руби, выполнить его обратные кавычки, а не функции system(), как это:

output = `python script.py` 

Это перехватывает вывод сценария Python в виде строки. Если вы хотите, чтобы он был массивом Ruby, вам нужно его проанализировать. Строковый синтаксис массива Ruby похож на синтаксис литерального списка списка Python, поэтому это не так сложно, как может показаться. Если вы можете найти что-то, что разбирает строки в массивах Ruby (кроме eval(), потому что это опасно), вы должны быть закрыты. Проблемы возникают, если у вас есть вещи помимо простых типов, None или потенциально строки с экранами в них.

Я скорее парень на Python, чем парень Ruby, но Ruby, похоже, не имеет ничего похожего на Python's ast.literal_eval (безопасный eval(), который принимает только литералы) в своей стандартной библиотеке. Тем не менее, я нашел parsr, который выглядит именно так.

Если список Python литералы вы получаете не действительны рубин, вы можете использовать JSON в качестве формата обмена:

# Python side 
import json, sys 
json.dump(main(), sys.stdout) 

# Ruby side 
require 'json' 
output = JSON.parse(`python script.py`) 
1

Если у вас есть сценарий Python print его результат, тогда он будет записан в result. Это «стандарт», т. Е. StdOut, это то, что читает рубиновый номер system.

Вам также необходимо, чтобы скрипт python фактически вызывал метод, когда он запускается из командной строки.

редактировать

Моя ошибка, используйте кавычку вместо system. И вместо использования регулярных выражений или строковых манипуляций для передачи данных между python и ruby ​​используйте стандартный формат сериализации, такой как json или yaml.

+0

Из того, что я могу сказать 'system()' возвращает 'true',' false' или 'nil' на основе кода возврата команды, а не вывода. – kindall

+0

@kindall updated –

2

Это питон test.py

import sys 

def main(): 
    ret = [1, 2] 
    print >> sys.stdout, ret 

main() 

Это рубиновый код.Р.Б.

require 'open3' 
require 'json' 

stdin, stdout, stderr = Open3.popen3("python test.py") 
stdout.each do |ele| 
    p ele #=> "[1, 2]\n" 
    p JSON.parse(ele) #=> [1, 2] 
end 

Затем выполнить рубиновый скрипт в оболочке

ruby test.rb 

Вам нужно по stdout, чтобы получить возвращаемое значение питона в рубиновый скрипт, и некоторых уродливых советы, я не нашел другого лучший способ в это время, но код может работать и принимать значение возврата python по крайней мере сейчас, возможно, вы можете попробовать его и искать лучшее решение непрерывно.

+0

'print' до стандартного вывода по умолчанию в Python. – kindall

+0

@kindall, вы правы, 'print >> sys.stdout, ret' может измениться на' print ret ' – Tsao