在Python 3中,这是由于
a bug in Python’s standard I/O library.在Python 3.3中修复了这个错误.
在Unix终端中,键入Ctrl D实际上并没有关闭进程的标准.但输入Enter或Ctrl D可确保使OS读取系统调用立即返回.所以:
>>> sys.stdin.read(100)
xyzzy (I press Enter here)
(I press Ctrl+D once)
'xyzzy\n'
>>>
sys.stdin.read(100)被委派给sys.stdin.buffer.read,它在循环中调用系统read(),直到它累积完整请求的数据量;或者系统read()返回0个字节;或发生错误. (docs) (source)
在第一行之后按Enter键导致系统read()返回6个字节. sys.stdin.buffer.read再次调用read()来尝试获得更多的输入.然后我按Ctrl D,导致read()返回0个字节.此时,sys.stdin.buffer.read放弃并返回刚刚收集的6个字节.
请注意,该进程仍然有我的终端在stdin,我仍然可以键入的东西.
>>> sys.stdin.read() (note I can still type stuff to python)
xyzzy (I press Enter)
(Press Ctrl+D again)
'xyzzy\n'
好.这是当这个问题最初被问及时被打倒的部分.它现在工作了但是在Python 3.3之前,有一个bug.
这个bug有点复杂 – 基本上这个问题是两个不同的层做同样的工作. BufferedReader.read()被写入,重复调用self.raw.read()直到它返回0个字节.然而,原始方法FileIO.read()执行了自己的循环直到零字节.所以第一次在Python中使用这个bug的Ctrl D,它会导致FileIO.read()返回6个字节到BufferedReader.read(),然后立即再次调用self.raw.read().第二个Ctrl D将导致返回0个字节,然后BufferedReader.read()将最终退出.
不幸的是,这个解释比我以前的解释要长得多,但它具有正确的美德.虫子就是这样…