How to display the redirected stdin in Python?

2020-02-12 04:57发布

I'm starting on a Python project in which stdin redirection is necessary, using code similar to below:

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)

The problem is, after the code runs, the following is displayed:

Type something: You typed in: Hello

Is there a way to modify my code such that the following is displayed instead?

Type something: Hello

You typed in: Hello

I've been searching high and low but have found no answer yet. I'll really appreciate if anyone has an idea. Thanks!

3条回答
一夜七次
2楼-- · 2020-02-12 05:35

I'm not sure why you would need to, but you could always do this:

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

Then again, swapping raw_input for your own implementation as needed would probably make more sense.

Edit: okay, based on your, comment it looks like you'll want to do some monkey patching. Something like this:

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

Of course, this might make the point of redirecting stdin moot.

查看更多
闹够了就滚
3楼-- · 2020-02-12 05:38

EDIT: After reading the other answers and comments I think I have found a good way to really redirect the stdin. Note that I have assumed that you will know the the inputs to the end user's raw_inputs need to be.

User's Code (Named 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

Your Test Script (Named whatever you like)

    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

Running the Script Yields

running some module with 5 raw_input requests
This is someone else's code asking its (0) raw_input: Value 1
stdin value: Value 1
This is someone else's code asking its (1) raw_input: Value 2
stdin value: Value 2
This is someone else's code asking its (2) raw_input: Value 3
stdin value: Value 3
This is someone else's code asking its (3) raw_input: Value 1
stdin value: Value 1
This is someone else's code asking its (4) raw_input: Value 2
stdin value: Value 2

Original Answer

Not sure if you're looking for such a literal answer but here it is

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)

Yields:

Type something: Hello

You typed in: Hello

查看更多
闹够了就滚
4楼-- · 2020-02-12 05:46

Do this.

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

Now the existing module is working with your raw_input, not the built-in raw_input. Yours can do anything to provide fake inputs and fake outputs.

查看更多
登录 后发表回答