Używając funkcji print() Pythona (lub według mojej najlepszej wiedzy, jakiejkolwiek innej generującej dane wyjściowe konsoli) w strukturach pętli i uruchamiając kod za pomocą reticulate w R, dane wyjściowe są drukowane dopiero po wykonaniu skończone. Na przykład weź następną pętlę, która przechodzi w stan uśpienia na 1,5 sekundy po każdej iteracji; numery serii są drukowane za jednym razem po przejściu pętli. To samo dotyczy zapisywania kodu Pythona w oddzielnym pliku .py, a następnie uruchamiania reticulate::py_run_file().

library(reticulate)

py_run_string("
import time

for i in range(5):
   print(str(i))
   time.sleep(1.5) # sleep for 1.5 sec
")

Czy ktoś wie, skąd się bierze takie zachowanie i, jeśli to możliwe, jak je obejść?

6
fdetsch 18 marzec 2020, 12:10

2 odpowiedzi

Najlepsza odpowiedź

Najwyraźniej czasami trzeba wymusić na Pythonie wyeksportowanie standardowego wyjścia. Możesz to zrobić, dodając sys.stdout.flush() do swojego kodu:

library(reticulate)

py_run_string("
import time
import sys

for i in range(5):
   print(str(i))
   time.sleep(1.5) # sleep for 1.5 sec
   sys.stdout.flush()
")

zobacz tutaj opisane z nohup

4
loki 18 marzec 2020, 09:28

Do wykorzystania w przyszłości, wymuszenie opróżnienia strumienia przez print(..., flush = True) działa również (jak zasugerowano tutaj ) i sprawia, że importowanie sys jest przestarzałe:

library(reticulate)

py_run_string("
import time

for i in range(5):
   print(str(i), flush = True)
   time.sleep(1.5)
")
2
fdetsch 27 marzec 2020, 05:46