2013-07-20 16 views
5

R'de, pipe() kullanarak bir boru bağlantısı açabilir ve ona yazabiliriz. Tam olarak anlamadığım şu durumu gözlemledim. s örneğin bir python boru kullanalım:R bağlantısında kapatmadan önce bir boru bağlantısından nasıl çıkış alınır?

: print() çıktısı hemen R konsolunda gösterilecektir, ama aslında çıkış I boru bağlantısını kapatmak sonra geliyor nedir bekliyordum

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) 

> 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 

Benim sorum şu ki, bağlantıyı kapatmadan önce çıkışı nasıl alabilirim? Bu sorunun

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

arka plan knitr engines: ya, bu capture.output() kullanarak çıkış yakalamak mümkün görünmüyor unutmayın. Python gibi yorumlanmış diller için, kalıcı bir "terminal" açabilmeyi diliyorum, böylece kod yazmayı ve çıktı almayı başarabileyim. Yine de, pipe()'un doğru yol olup olmadığından emin değilim.

cevap

5

Python, girişin etkileşimli olmadığını fark eder ve ayrıştırmak ve kodu yürütmek için bağlantı kapatılana kadar bekler. Etkileşimli modda kalmak için -i seçeneğini kullanabilirsiniz. (ama çıktı biraz karıştırılmış).

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) 

Gerçek sorununuz daha karmaşıktır: hem aynı bağlantıyı okumanız hem de yazmanız gerekir. Bunu taşınabilir bir şekilde nasıl yapacağımı bilmiyorum, ancak bunları destekleyen platformlarda bir boru ve adlandırılmış bir boru ("fifo") kullanabilirsiniz.

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" 
İlgili konular