2017-02-23 19 views
1

私のPythonスクリプトは、このようなものです:ルビー:Pythonスクリプトの戻り値を取得

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

と私はこのようなルビーからPythonスクリプトを呼び出す:

output = system("python script.py") 

print output 

は、出力の値がtrueであるしかし、 。私は[1、2]に行きたいです。私の質問は、私はPythonスクリプトの戻り値を取得する方法です?

答えて

1

まず、Pythonスクリプトで値を返すのではなく出力してください。print main()を最後に追加すると、戻り値main()が表示されるようになります。

第二には、Rubyの側で、このように、バッククォートではなくsystem()機能とそれを実行します。

output = `python script.py` 

は、これは文字列としてPythonスクリプトの出力をキャプチャします。あなたがRuby配列としてそれを必要とするならば、それを解析する必要があります。 Rubyの配列リテラル構文はPythonのリストリテラル構文と似ていますので、これは見た目ほど難しいものではありません。文字列をRuby配列にパースするものが見つかった場合(危険なのでeval()のほかに)、あなたはカバーされるべきです。シンプルな型の他に、None、あるいはエスケープされた文字列があると問題が発生します。

私はRubyの人よりもPythonの人ですが、標準ライブラリにPythonの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は –

2

これは、Pythonのtest.py

import sys 

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

main() 

これはありますルビーコードテスト。RB

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スクリプトでPythonの戻り値を取得するstdoutにより必要がある、といくつかの醜いヒントによって、私は他のを見つけられませんでしたシェルに

ruby test.rb 

をRubyスクリプトを実行しますこの時点ではより良い方法ですが、コードは少なくとも今はPythonの戻り値を受け入れて受け入れることができます。それを試してより良い解決策を連続的に検索することができます。

+0

を更新しました。 'print'はデフォルトでPythonで標準出力に移動します。 – kindall

+0

@kindall、そうです、 'print >> sys.stdout、ret'は' print ret 'に変更できます – Tsao

関連する問題