作为一个非常熟悉os和命令行进程的php程序员(各种各样),我很惊讶在python中,用户在与程序交互过程中输入的所有内容似乎都被缓冲,等待倾吐第一次使用raw_input
(例如)。
发现一些代码要在raw_input
之前调用,这似乎“解决”了osX上的问题,虽然据说它提供了access to windows功能:
class FlushInput(object):
def flush_input(self):
try:
import msvcrt
while msvcrt.kbhit():
msvcrt.getch()
except ImportError:
import sys, termios
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
我是否正确理解stdin和stdout,stderr方法会因操作系统而异?
我想像Django这样的框架可能有内置的方法来简化交互性,但它基本上只需要几行代码来告诉python“在被邀请之前不接受任何输入吗?”
答案 0 :(得分:5)
唉唉。如果我正确理解这一点(并且我确信理解需要很多改进),答案是肯定的,stdin, stdout, stderr
,“标准”输入,输出和错误流及其处理可能与(运行)不同系统到系统,因为它们是操作系统的产品而不是任何特定的编程语言。
“告诉python在请求输入之前忽略stdin”的期望将自动源于对“终端”的思考,就好像它是打字机一样。如果打字机的目标是以人类可读的格式记录信息串,则终端的目标是传输最终将被转换为机器可读格式的信息,并返回人类可读的响应。
我们大多数人来到计算机当前认为是“终端”实际上是一种称为终端的物理机器的虚拟娱乐,它曾经是数据输入和读取计算机处理器的方法, 对?文本编辑器是一个应用程序,可以从键盘创建虚拟类型编写器,监视和处理操作系统的功能以及包含的程序库。
像mac OS终端这样的应用程序,甚至我们用来通过和ssh连接与其他服务器进行交互的应用程序实际上是创建了一个虚拟终端,通过它我们可以与处理器交互,但是将信息发送到stdin并从stdout接收strerr。当我们输入的字母出现在终端屏幕上时,这是因为它被“回显”回终端窗口。
因此没有理由期望python或任何其他语言与终端之间的关系默认阻止来自终端的输入流。
上面的代码使用pythons exception handling
提供了两种替代方法,在代表程序执行某些活动之前刷新输入流。在OSX平台上代码:
import sys, termios
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
导入系统,以便我们可以访问stdin和termios,这是用于管理实际管理两个虚拟终端的POSIX(LINUX,UNIX)应用程序的python模块 - 一个介于自身和用户之间,另一个介于自身和操作系统。 tcflush
似乎是一个接受至少两个参数的函数 - 第一个是要刷新的WHICH流 - file descriptor
(fd),第二个是要刷新的队列。在这种情况下,我不确定文件描述符和队列之间的区别是什么,除了可能fd包含尚未添加到队列的数据并且队列包含不再包含在fd中的数据
msvcrt
是用于与终端的任何Windows版本进行交互(管理)的python模块,我猜msvcrt.kbhit()
和msvcrt.getch()
是用于刷新其输入队列的函数。
可以交换该函数的UNIX和Windows调用,以便不是说try:
以windows方式执行它,如果ImportError
被提升到UNIX,那么我们{{1}首先是UNIX方式:
try:
这里有a termios introduction帮助澄清了这个过程。