2017-10-15 14 views
0

Je veux décorer python.exe. Par exemple, il peut être juste Input:\n quand nous écrivons stdin et Output:\n quand on lit à partir stdout préfixes en mode interactif:Décorez le programme CLI avec sous-processus.Popen

originale python.exe:

$ python 
Python 3.6.1 |Anaconda custom (64-bit)| (default, Mar 22 2017, 20:11:04) [MSC v.1900 64 bit (AMD64)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> print(2) 
2 
>>> 2 + 2 
4 
>>> 

exceptées décorées python.exe:

$ decorated_python 
Output: 
Python 3.6.1 |Anaconda custom (64-bit)| (default, Mar 22 2017, 20:11:04) [MSC v.1900 64 bit (AMD64)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 
Input: 
print(2) 
Output: 
2 
>>> 
Input: 
2 + 2 
Output: 
4 
>>> 

Je pense que cela devrait ressembler à ceci:

import subprocess 

pid = subprocess.Popen("python".split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

while True: 
    pid.stdin.write(input('Input:\n').encode()) 
    print('Output:\n' + pid.stdout.readlines()) 

Mais pid.stdout.readlines() jamais fait.

J'ai aussi essayé d'utiliser la méthode communicate mais il travaille seulement la première fois:

import subprocess 

pid = subprocess.Popen("python".split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

while True: 
    print('Output:\n', pid.communicate(input('Input:\n').encode())) 

Test:

Input: 
print(1) 
Output: 
(b'1\r\n', b'') 
Input: 
pritn(1) 
Traceback (most recent call last): 
    File "C:/Users/adr-0/OneDrive/Projects/Python/AdrianD/temp/tmp.py", line 6, in <module> 
    print('Output:\n', pid.communicate(input('Input:\n').encode())) 
    File "C:\Users\adr-0\Anaconda3.6\lib\subprocess.py", line 811, in communicate 
    raise ValueError("Cannot send input after starting communication") 
ValueError: Cannot send input after starting communication 

Peut-être me manque quelque chose, parce que si je viens de mettre 2 dans python je vais obtenez 2. Mais je ne peux pas obtenir ce 2 avec la méthode communicate:

python pur:

>>> 2 
2 

Décoré avec méthode communicate:

Input: 
2 
Output: 
(b'', b'') 

Répondre

1

si vous regardez la documentation python, vous pouvez constater que lors de l'utilisation stdin/stdout = PIPE, il est fortement déconseillé de ne pas utiliser les actions de lecture/écriture sur ces flux, car cela peut provoquer un blocage - ce que vous avez réellement vécu en lisant readlines: https://docs.python.org/2/library/subprocess.html#popen-objects

Le problème suivant est dû

« Popen.communicate() est une méthode d'assistance qui fait une écriture unique de données à stdin et crée des threads pour extraire des données à partir stdout et stderr. Il ferme stdin quand il a fini d'écrire des données et lit stdout et stderr jusqu'à ce que ces tuyaux se ferment. Vous ne pouvez pas faire une deuxième communication parce que l'enfant a déjà terminé le temps retourne « @tdelaney

plus:. Multiple inputs and outputs in python subprocess communicate

manière générale, faire des enfants processus interactif est difficile, vous pouvez essayer d'utiliser https://pexpect.readthedocs.io/en/stable/

+0

Merci pour votre réponse, mais malheureusement 'pexpect' ne fonctionne pas sous Windows ... – ADR