2011-04-28 6 views
5

Je commence un projet Python dans lequel la redirection de stdin est nécessaire, en utilisant un code similaire à ci-dessous:Comment afficher le stdin redirigé en Python?

import sys 
import StringIO 

s = StringIO.StringIO("Hello") 
sys.stdin = s 
a = raw_input("Type something: ") 
sys.stdin = sys.__stdin__ 
print("You typed in: "+a) 

Le problème est, après le code est exécuté, le message suivant apparaît:

Tapez quelque chose: Vous avez tapé: Bonjour

Existe-t-il un moyen de modifier mon code de sorte que ce qui suit est affiché à la place?

Type de quelque chose: Bonjour

Vous avez tapé dans: Bonjour

J'ai cherché haut et bas, mais ai trouvé pas encore de réponse. J'apprécierai vraiment si quelqu'un a une idée. Merci!

+3

"La redirection stdin est nécessaire"? Vraiment? Cela semble être une situation impossible. Pourquoi ne pas remplacer 'raw_input' par un objet appelable qui fait ce que vous voulez? –

+0

Je comprends que ce n'est pas une situation courante, mais c'est vraiment nécessaire. Le code ci-dessus est juste un exemple très simple; en réalité, je dois exécuter le code d'autres personnes qui demande des informations, donc je ne peux pas changer la façon dont ils codent leurs programmes. – dangmai

+0

Vous ne changez pas leur code. Vous redéfinissez une fonction intégrée avec votre propre version, importez leur code, et exécutez leur code en utilisant votre version de l'intégré. –

Répondre

2

Je ne sais pas pourquoi vous auriez besoin, mais vous pouvez toujours le faire:

a = raw_input("Type something: ") 
if sys.stdin is not sys.__stdin__: 
    print(a) 
print("You typed in: "+a) 

Là encore, l'échange raw_input pour votre propre mise en œuvre, au besoin serait probablement plus logique.

Editer: d'accord, d'après votre commentaire, il semblerait que vous vouliez faire quelques corrections de singe. Quelque chose comme ceci:

old_raw_input = raw_input 

def new_raw_input(prompt): 
    result = old_raw_input(prompt) 
    if sys.stdin is not sys.__stdin__: 
     print result 
    return result 

raw_input = new_raw_input 

Bien sûr, cela pourrait faire le point de rediriger sans objet stdin.

+0

Merci pour votre réponse! Cependant, ce n'est pas ce dont j'ai besoin. J'essaie d'exécuter les codes d'autres personnes qui demandent des commentaires, donc je ne peux pas changer la façon dont leurs programmes sont écrits. – dangmai

+0

On dirait que vous devriez assigner le raw_input à votre propre implémentation. –

+0

C'est exactement ce que je veux! Merci beaucoup!Je ne savais pas que nous pouvions faire ce truc bizarre avec Python :) – dangmai

1

EDIT: Après avoir lu les autres réponses et commentaires, je pense que j'ai trouvé un bon moyen de vraiment rediriger le stdin. Notez que j'ai supposé que vous connaissez les entrées de raw_inputs de l'utilisateur final.

Code de l'utilisateur (Nommé some_module.py)

print "running some module with 5 raw_input requests" 
for x in range(5): 
    value = raw_input("This is someone else's code asking its (" + str(x) + ") raw_input: ") 
    print 'stdin value: ' + value 

Votre Script de test (du nom que vous voulez)

import sys 
    class MY_STD_IN(object): 
     def __init__(self, response_list): 
      self.std_in_list = response_list 
      self.std_in_length = len(response_list) 
      self.index = 0 

     def readline(self): 
      value = self.std_in_list[self.index]  
      print value 
      if self.index < self.std_in_length -1: 
       self.index += 1 
      else: 
       self.index = 0 

      return value 

    predetermined_stdin_responses = ['Value 1\r', 'Value 2\r', 'Value 3\r'] 
    sys.stdin = MY_STD_IN(predetermined_stdin_responses) 

    import some_module 

Exécution du script Rendements

exécutant un module avec 5 raw_input demande
Ceci est le code de quelqu'un d'autre demandant son (0) raw_input: Valeur 1
valeur stdin: Valeur 1
Ceci est quelqu'un d'autre code demandant son (1) raw_input: Valeur 2
valeur stdin: Valeur 2
Ceci est quelqu'un d'autre code demandant son (2) raw_input Valeur 3
valeur stdin: valeur 3
Ceci est quelqu'un d'autre code demandant son (3) raw_input valeur 1
valeur stdin: valeur 1
Ceci est quelqu'un d'autre code demandant son (4) raw_input: valeur 2
valeur stdin: valeur 2

Réponse originale

Je ne sais pas si vous êtes à la recherche d'une telle réponse littérale, mais ici il est

import sys 
import StringIO 

s = StringIO.StringIO("Hello") 
sys.stdin = s 
a = raw_input("Type something: ") 
sys.stdin = sys.__stdin__ 
print(a+"\nYou typed in: "+a) 

Rendement:

Type de quelque chose: Bonjour

Vous avez tapé: Bonjour

+0

Merci pour votre réponse, mais ce n'est pas ce dont j'ai besoin. Je dois exécuter les codes d'autres personnes, donc je ne peux pas changer la façon dont ils codent leurs programmes. Tout ce que je peux faire (que je sache) est de manipuler en quelque sorte stdin et stdout. – dangmai

+0

Pourriez-vous donner plus d'exemples de ce qu'est leur code et comment vous avez l'intention d'interagir avec lui? Signification voulez-vous contrôler le raw_input() de leur programme avec vos propres données? –

+0

Oui, c'est correct. J'ai besoin de vérifier la réponse d'un élève en alimentant les données dans sa fonction (soit en fournissant un argument ou via stdin) et ensuite comparer la sortie standard à une réponse fournie. – dangmai

3

Pour ce faire.

class MyRawInputFakeOutObject(object): 
    def __init__(self, the_fake_out_input_text): 
     self.input= the_fake_out_input_text 
    def __call__(self, prompt): 
     print(prompt) 
     return self.input 

raw_input= MyRawInputFakeOutObject("Hello") 

import some_existing_module 

some_existing_module.the_existing_main() 

Maintenant, le module existant travaille avec votre raw_input, pas intégré raw_input. Le vôtre peut faire n'importe quoi pour fournir de fausses entrées et de fausses sorties.

+0

bonne réponse! Cependant, je trouve le code de ian b un peu plus facile à utiliser. Les deux devraient résoudre mon problème cependant. Merci beaucoup! – dangmai

+0

Est-ce que cette méthode fonctionnerait pour du code qui n'était pas divisé en modules? Par exemple, si on a donné un script qui n'avait pas de fonctions ou de main, la commande import ne lancerait-elle pas le script (ie avant que red_input ne soit redéfini)? Juste une pensée. –

+0

@Adam Lewis: Chaque fichier Python ** est ** un module. Par définition. Vous ne pouvez pas éviter de décomposer Python en modules. Quand vous avez un "script", c'est un module. L'importer va l'exécuter. Bien que votre commentaire comporte beaucoup de confusion, il signale un changement nécessaire pour gérer ces scripts mal écrits sans section 'if __name __ ==" __ main __ ":'. –