【问题标题】:How to display the redirected stdin in Python?如何在 Python 中显示重定向的标准输入?
【发布时间】:2011-08-14 07:35:06
【问题描述】:

我正在开始一个 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)

问题是,代码运行后,显示如下:

输入一些东西:你输入:你好

有没有办法修改我的代码以显示以下内容?

输入一些东西:你好

你输入:你好

我一直在寻找高低,但还没有找到答案。如果有人有想法,我将不胜感激。 谢谢!

【问题讨论】:

  • “标准输入重定向是必要的”?真的吗?这似乎是一个不可能的情况。为什么不用你想要的可调用对象替换raw_input
  • 我明白这不是常见的情况,但确实有必要。上面的代码只是一个非常简单的例子;实际上,我需要运行其他人的要求输入的代码,所以我无法改变他们编写程序的方式。
  • 您无需更改他们的代码。您使用自己的版本重新定义内置函数,导入他们的代码,并使用您的内置版本运行他们的代码。
  • 哦,我明白你的意思了。但是,我仍然想不出使用您的想法的实现是令人满意的。您介意发布一段可能帮助我更接近解决方案的示例代码吗?非常感谢!

标签: python redirect stdin


【解决方案1】:

这样做。

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

现在现有模块正在使用您的raw_input,而不是内置的raw_input。你可以做任何事情来提供假输入和假输出。

【讨论】:

  • 很好的答案!但是,我发现 ian b 的代码更易于使用。两者都应该解决我的问题。非常感谢!
  • 这种方法是否适用于未分解为模块的代码?例如,如果一个脚本没有定义函数或主函数,那么 import 命令不会只运行脚本(即在重新定义 raw_input 之前)吗?只是一个想法。
  • @Adam Lewis:每个 Python 文件都是一个模块。根据定义。你无法避免将 Python 分解为模块。当你有一个“脚本”时,它就是一个模块。导入它将运行它。虽然您的评论有很多混乱,但它确实指出了处理那些没有if __name__=="__main__": 部分的写得很糟糕的脚本所需的更改。
  • 关于模块注释的要点。您的更改解决了我试图传达的内容。我之所以提出它,是因为我可以看到一位老师的助理以这种方式对 Python 作业进行评分。也就是说,如果要对家庭作业进行评分,我怀疑编写良好的代码是否正常。感谢您的澄清!
  • 实际上亚当您刚刚描述了我的确切情况(我是一个助手,正在编写一个程序来自动检查学生的答案):) 这就是为什么我不能自己更改部分代码的原因。再次感谢大家!
【解决方案2】:

编辑:在阅读了其他答案和 cmets 之后,我想我找到了一种真正重定向标准输入的好方法。请注意,我假设您知道最终用户的 raw_inputs 的输入需要是什么。

用户代码(命名为 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

你的测试脚本(随便命名)

    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

运行脚本产量

运行带有 5 个 raw_input 请求的模块
这是别人的代码询问其 (0) raw_input: Value 1
标准输入值:值 1
这是别人的代码询问其 (1) raw_input: Value 2
标准输入值:值 2
这是别人的代码询问其 (2) raw_input: Value 3
标准输入值:值 3
这是别人的代码询问其 (3) raw_input: Value 1
标准输入值:值 1
这是别人的代码询问其 (4) raw_input: Value 2
标准输入值:值 2

原答案

不确定您是否正在寻找这样一个字面意思的答案,但在这里

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)

产量:

输入一些东西:你好

你输入:你好

【讨论】:

  • 感谢您的回答,但这不是我需要的。我必须运行其他人的代码,所以我无法改变他们编写程序的方式。我所能做的(据我所知)就是以某种方式操纵标准输入和标准输出
  • 您介意提供更多示例,说明他们的代码是什么以及您打算如何与之交互吗?意思是你想用你自己的数据来控制他们程序的 raw_input() 吗?
  • 是的,没错。我需要通过将数据输入他们的函数(通过提供参数或通过标准输入)来检查学生的答案,然后将标准输出与提供的答案进行比较。
【解决方案3】:

我不确定你为什么需要这样做,但你总是可以这样做:

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

再一次,根据需要将raw_input 换成您自己的实现可能更有意义。

编辑:好的,根据您的评论,您似乎想要做一些猴子补丁。像这样的:

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

当然,这可能会使重定向标准输入毫无意义。

【讨论】:

  • 感谢您的回答!然而,这不是我需要的。我正在尝试运行其他人的要求输入的代码,因此我无法更改他们的程序编写方式。
  • 听起来您应该将 raw_input 修补到您自己的实现中。
  • 这正是我想要的!非常感谢!我从来不知道我们可以用 Python 做这个疯狂的猴子补丁 :)
  • 如果您使用的是 3.x,this 很有用。
猜你喜欢
  • 2012-11-04
  • 2022-11-10
  • 2011-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多