6

R では、 を使用してパイプ接続を開き、pipe()それに書き込むことができます。次の状況を観察しましたが、よくわかりません。pythonたとえば、パイプを使用してみましょう。

z = pipe('python', open='w+')

cat('x=1\n', file=z)
cat('print(x)\n', file=z)
cat('print(x+2)\n', file=z)
cat('print(x+2\n', file=z)
cat(')\n', file=z)

close(z)

私が期待していたのは、出力print()がすぐに R コンソールに表示されることでしたが、実際には、パイプ接続を閉じた後にのみ出力が表示されます。

> z = pipe('python', open='w+')
> 
> cat('x=1\n', file=z)
> cat('print(x)\n', file=z)
> cat('print(x+2)\n', file=z)
> cat('print(x+2\n', file=z)
> cat(')\n', file=z)
> 
> close(z)
1
3
3

私の質問は、接続を閉じる前に出力を取得するにはどうすればよいですか? を使用して出力をキャプチャすることもできないように見えることに注意してくださいcapture.output()

> z = pipe('python', open='w+')
> 
> cat('x=1\n', file=z)
> cat('print(x)\n', file=z)
> cat('print(x+2)\n', file=z)
> cat('print(x+2\n', file=z)
> cat(')\n', file=z)
> 
> x = capture.output(close(z))
1
3
3
> x
character(0)

この質問の背景はknitrエンジンです。Python のようなインタープリター言語の場合、永続的な「ターミナル」を開いてコードを書き続け、そこから出力を取得できるようにしたいと考えています。pipe()ただし、正しい方法かどうかはわかりません。

4

1 に答える 1

6

Python は、入力がインタラクティブではないことを認識し、接続が閉じられるまで待機してコードを解析および実行します。このオプションを使用して、-i強制的にインタラクティブ モードのままにすることができます。(ただし、出力は少し壊れています)。

z = pipe('python -i', open='w')
cat('x=1\n', file=z)
cat('print(x)\n', file=z)
cat('print(x+2)\n', file=z)
cat('print(x+2\n', file=z)
cat(')\n', file=z)
Sys.sleep(2)
# Python 2.7.4 (default, Apr 19 2013, 18:28:01) 
# [GCC 4.7.3] on linux2
# Type "help", "copyright", "credits" or "license" for more information.
# >>> >>> 1
# >>> 3
# >>> ... 3
# >>> 
close(z)

実際の問題はもっと複雑です。同じ接続に対して読み取りと書き込みの両方が必要です。移植可能な方法でそれを行う方法はわかりませんが、パイプと名前付きパイプ (「fifo」) をサポートするプラットフォームで使用できます。

stopifnot( capabilities("fifo") )
system('mkfifo /tmp/Rpython.fifo')
output <- fifo('/tmp/Rpython.fifo', 'r')
input  <- pipe('python -i > /tmp/Rpython.fifo', 'w')
python_code <- "
x=1
print(x)
print(x+2)
print(x+2
)
"
cat( python_code, file = input )
flush( input )
Sys.sleep(2) # Wait for the results
result <- readLines(output)
result
# [1] "1" "3" "3"
于 2013-07-20T22:08:57.457 に答える