【问题标题】:Change python stdin stream to Windows Console input将 python 标准输入流更改为 Windows 控制台输入
【发布时间】:2015-02-02 18:19:20
【问题描述】:

我想运行一个 python 3 脚本,通过标准输入手动输入数据给它一个文件。

例如假设我想用一行打印输入的内容。名为app.py 的脚本如下所示:

from sys import stdin

print("Input says:"+stdin.readline())

然后,我可以通过以下两种方式运行它:

1.将文件作为标准输入传递

python app.py < input.txt

2。提示用户输入

python app.py

我的问题是,在这两种情况下,阅读标准输入后,我想提示用户输入一些额外的数据。按照前面提到的示例,它将是:

from sys import stdin

print("Input says:"+stdin.readline())

print("Did you like that? (Yes/No)")
ans = input() # This line is the issue!
if( ans == "Yes"):
    print("You liked it!")    

上面注释的行非常适用于案例 2,但对于案例 1,它会抛出 EOFError: EOF when reading a line 错误,因为它试图从文件中读取。

我想知道在那条线之前我是否可以做类似的事情

sys.stdin = SOMETHING

其中 SOMETHING 代表 Windows 控制台输入。我认为如果我能做到这一点,那么这两种情况都会正常工作。

【问题讨论】:

  • 您可以通过win32console api 访问控制台。
  • 试试CONCONIN$。可能会起作用,具体取决于 Python 究竟做了什么。
  • 你的问题不清楚;您想从 console 提示一些输入,即使您提供了一个文件为 sys.stdin

标签: python windows python-3.x input stdin


【解决方案1】:

您可以认为这两种情况是相同的(忽略差异)。您的脚本只从标准输入读取两行。 stdin 可以从文件重定向,也可以附加到控制台,您的脚本在许多情况下都可以正常工作:

print("Read the first line from stdin", input())
answer = input("Did you like that? (Yes/No): ") # read 2nd line
if answer == "Yes":
    print("You liked it!")

executable code example

问:我想要的是从文件或控制台读取一些输入(取决于运行应用程序时使用的参数)。我希望它们始终从控制台读取其他一些行。

无论标准输入是否从文件重定向,要直接从控制台读取,您可以使用msvcrt.getwch()。请参阅getpass.win_getpass() 中的示例用法。

如果您在接受 Unicode 输入时遇到问题;安装win_unicode_console package。您可以为您的 python 安装或特定用户或整个脚本或临时使用win_unicode_console.enable()/.disable() 全局启用它。要强制它使用控制台,如果 stdin 被重定向或call ReadConsoleW() yourself (cumbersome),您可以临时设置sys.stdin=None

【讨论】:

  • 如果我使用文件作为输入,answer = input("Did you like that? (Yes/No): ") 行会抛出 EOFError。无论如何,这应该会发生,因为它会尝试从文件中读取输入!
  • @Sam:你试过点击“可执行代码示例”链接吗?没有EOFError。您认为 ideone 如何为脚本提供输入? (没有人输入输入)。 EOFError 可能会在文件末尾引发(可移植代码应该处理 EOFError 异常)——我不知道确切的条件:这本身就是一个好问题。我回答的重点是您应该忽略以下区别:cat input | python your_script.py&lt;input python your_script.py 和手动从终端/控制台提供输入(除非您有特定理由不忽略它)。
  • 是的,因为 stdin 既有第一行(执行前存在的数据)又有“是”行,该行应该由用户在运行时键入。基本上,我想要的是将引用 sys.stdin 从与我作为输入(而不是参数!)提供的文件相关的流更改为与控制台输入相关的流。
  • @Sam:你想从文件中读取第一行,从控制台读取第二行吗?可以在程序中间重定向sys.stdin 以从控制台读取(只需分配sys.stdin 直接从控制台读取的类似文件的对象,例如,使用Win32 API(它可能对input() 没有任何影响) ; 在这种情况下使用sys.stdin.readline())或特殊文件名,如 cmets 中建议的con。但更好的选择是避免在程序中间重定向标准输入;改为使用文件名从文件中读取。
  • @Sam:我已经更新了答案,明确提及如何直接从控制台读取,无论 stdin 是否被重定向。
猜你喜欢
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多