4 votes

Utilisation de Python Popen pour lire la dernière ligne

J'ai un programme Python simple :

test.py :

import time
for i in range(100000):
    print i
    time.sleep(0.5)

Je veux utiliser un autre programme qui exécute le premier afin de lire la dernière ligne de sortie pendant que le premier programme compte.

import subprocess

process = subprocess.Popen("test",stdout=PIPE)
sleep(20) # dort pendant un laps de temps arbitraire
print stdout.readlines()[-1]

Le problème est que process.stdout.readlines() attend que test.py ait fini son exécution. Y a-t-il un moyen de lire la dernière ligne écrite dans la sortie pendant que le programme s'exécute ?

3voto

J.F. Sebastian Points 102961

Vous pouvez utiliser collections.deque pour sauvegarder uniquement le nombre spécifié de dernières lignes :

#!/usr/bin/env python
import collections
import subprocess
import time
import threading

def read_output(process, append):
    for line in iter(process.stdout.readline, ""):
        append(line)

def main():
    process = subprocess.Popen(["program"], stdout=subprocess.PIPE)
    # sauvegarde des dernières lignes `number_of_lines` de la sortie du processus
    number_of_lines = 1
    q = collections.deque(maxlen=number_of_lines)
    t = threading.Thread(target=read_output, args=(process, q.append))
    t.daemon = True
    t.start()
    #
    time.sleep(20)

    # imprime les lignes sauvegardées
    print ''.join(q),
    # le processus est toujours en cours d'exécution
    # décommentez si vous ne voulez pas attendre que le processus se termine
    ##process.terminate() # si cela ne se termine pas; utilisez process.kill()
    process.wait()

if __name__=="__main__":
    main()

Voir d'autres solutions similaires à tail qui n'affichent que la partie de la sortie

Voir ici si votre programme enfant utilise un buffering par bloc (au lieu d'un buffering par ligne) pour sa sortie standard lors de son exécution de manière non interactive.

1voto

amoffat Points 192

Assez trivial avec sh.py:

import sh

def process_line(line):
    print line

process = sh.python("test.py", _out=process_line)
process.wait()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X