6

pipe()在 R 中,我们可以使用和写入来打开管道连接。我观察到以下我不太明白的情况。让我们以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 notices that the input is not interactive and waits until the connection is closed to parse and execute the code. You can use the -i option to force it to stay in interactive mode. (but the output is a bit mangled).

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)

Your actual problem is more complicated: you need to both read and write to the same connection. I do not know how to do that in a portable way, but you can use a pipe and a named pipe (a "fifo") on platforms that support them.

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 回答