2013-07-20 42 views
5

Trong R, chúng ta có thể mở một kết nối đường ống bằng cách sử dụng pipe() và ghi vào nó. Tôi quan sát tình huống sau mà tôi không hiểu lắm. Hãy sử dụng một ống python ví dụ:làm thế nào để có được đầu ra từ một kết nối đường ống trước khi đóng nó trong 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) 

Những gì tôi đã mong là đầu ra từ print() sẽ được hiển thị ngay lập tức trong R console, nhưng thực tế là sản phẩm chỉ đến sau khi tôi đóng kết nối ống:

> 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 

Vì vậy, câu hỏi của tôi là, làm cách nào để có được kết quả trước khi tôi đóng kết nối? Lưu ý rằng nó dường như không thể để nắm bắt đầu ra sử dụng capture.output(), một trong hai:

> 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) 

Nền của câu hỏi này là knitr engines. Đối với các ngôn ngữ thông dịch như Python, tôi ước tôi có thể mở một "terminal" liên tục để tôi có thể tiếp tục viết mã vào nó và lấy đầu ra từ nó. Tôi không chắc chắn nếu pipe() là cách chính xác để đi, mặc dù.

Trả lời

5

Python thông báo rằng đầu vào không tương tác và chờ cho đến khi kết nối được đóng để phân tích và thực thi mã. Bạn có thể sử dụng tùy chọn -i để buộc thiết bị ở chế độ tương tác. (nhưng đầu ra là một chút sai lầm).

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) 

Vấn đề thực tế của bạn phức tạp hơn: bạn cần cả đọc và ghi vào cùng một kết nối. Tôi không biết làm thế nào để làm điều đó một cách di động, nhưng bạn có thể sử dụng một đường ống và một ống được đặt tên (một "fifo") trên nền tảng hỗ trợ chúng.

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" 
Các vấn đề liên quan