You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非阻塞模式下sys.stdin.read(10)返回值逻辑的技术问询

非阻塞模式下sys.stdin.read(10)返回值逻辑的技术问询

能不能请大家帮我解释下这段代码里sys.stdin.read(10)的返回值逻辑呀?我对照官方文档推导了半天,实在理不清头绪,卡进死胡同了。

import sys, os

os.set_blocking(sys.stdin.fileno(), False)
c = sys.stdin.read(10)
print(c)

下面是我从上到下的推导过程,肯定哪里出了问题,最后越想越乱:

  1. 首先,根据文档描述,sys.stdin属于“和open()返回的类似的常规文本文件”,所以我推断它是一个TextIOWrapper对象。
  2. 关于TextIOWrapper,文档里是这样定义的:

    一个提供高级访问能力的缓冲文本流,基于BufferedIOBase缓冲二进制流构建,继承自TextIOBase。

  3. 所有io.TextIO相关的文档都没有区分阻塞和非阻塞模式,特别是io.TextIOBase.read(size=-1, /)的方法说明:

    读取并返回最多size个字符的字符串。如果size为负数或None,会持续读取直到遇到EOF。

  4. 接着看BufferedIOBase的文档,里面提到像read()这类方法的行为:

    [...] 如果底层原始流处于非阻塞模式,且无法读取或写入足够数据时,可能会抛出BlockingIOError。

  5. 更让我困惑的是,我在CPython里发现sys.stdout.buffer是存在的,它是BufferedReader对象(继承自BufferedIOBase),而io.BufferedReader.read(size=-1, /)的文档说明是:

    读取并返回size字节的数据;如果没有指定size或size为负数,会读取到EOF,或者在非阻塞模式下如果调用会导致阻塞的话就停止读取。
    (顺带提一句,我英语不太好,不太理解“非阻塞模式下如果调用会导致阻塞的话就停止读取”这种情况到底会返回什么内容。)

  6. 最后,我查了PEP3116,里面提到(注意原文的IOError现在已经被OSError替代了):

    在缓冲I/O和文本I/O层,如果读写操作因为非阻塞条件失败,会抛出一个IOError,且errno设为EAGAIN。

现在我就懵了:BufferedIOBase说“可能会抛出”异常,PEP3116明确说“会抛出”异常,但BufferedReader的文档里不仅没提抛异常,反而说会停止读取。这几个文档的描述看起来互相矛盾,到底sys.stdin.read(10)在非阻塞模式下的返回值逻辑应该是怎样的呀?

备注:内容来源于stack exchange,提问作者JtTest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 13:25:30