异常不是来自Python,而是来自操作系统,该操作系统不允许在管道上进行搜索。(如果您从常规管道重定向输出,即使它是标准输入,也可以对其进行查找。)这就是为什么即使类相同,在一种情况下而不是另一种情况下出现错误的原因。
用于预读的经典Python 2解决方案是将流包装在您自己的实现预读的流实现中:
class Peeker(object):
def __init__(self, fileobj):
self.fileobj = fileobj
self.buf = cStringIO.StringIO()
def _append_to_buf(self, contents):
oldpos = self.buf.tell()
self.buf.seek(0, os.SEEK_END)
self.buf.write(contents)
self.buf.seek(oldpos)
def peek(self, size):
contents = self.fileobj.read(size)
self._append_to_buf(contents)
return contents
def read(self, size=None):
if size is None:
return self.buf.read() + self.fileobj.read()
contents = self.buf.read(size)
if len(contents) < size:
contents += self.fileobj.read(size - len(contents))
return contents
def readline(self):
line = self.buf.readline()
if not line.endswith('\n'):
line += self.fileobj.readline()
return line
sys.stdin = Peeker(sys.stdin)
在Python 3中,sys.stdin
在窥视未解码流的同时支持完整操作是很复杂的-stdin.buffer
如上所示,将其包装,然后在可窥视的流上实例化一个新TextIOWrapper
对象,并将其安装TextIOWrapper
为sys.stdin
。
但是,因为你只需要在偷看sys.stdin.buffer
,上面的代码将工作得很好,转换后cStringIO.StringIO
,以io.BytesIO
和'\n'
到b'\n'
。