input() 函数的输入可以有多大?

How big can the input to the input() function be?

我可以为 input() 函数提供多大的输入?

不幸的是,没有简单的方法来测试它。在使用大量复制粘贴后,我无法让 input 在我提供的任何输入上失败。 (我最终放弃了)

input 函数的 documentation 没有提及任何相关内容:

If the prompt argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.

所以,我猜没有限制?有谁知道是否有,如果有,多少钱?

当然有,不可能是无限的*。我认为需要突出显示的文档中的关键句子是:

[...] The function then reads a line from input, converts it to a string (stripping a trailing newline) [...]

(强调我的)

由于它将您提供的输入转换为 Python str 对象,因此它实际上转换为:"Its size has to be less than or equal to the largest string Python can create".

之所以没有给出明确的大小,可能是因为这是一个实现细节。对 Python 的所有其他实现强制执行最大大小没有多大意义。

*在 CPython 中,至少,字符串的最大大小受其 index 允许的大小限制(参见 PEP 353).也就是说,当您尝试索引它时,括号 [] 中的数字可以有多大:

>>> s = ''
>>> s[2 ** 63]

IndexErrorTraceback (most recent call last)
<ipython-input-10-75e9ac36da20> in <module>()
----> 1 s[2 ** 63]

IndexError: cannot fit 'int' into an index-sized integer

(试试前面的2 ** 63 - 1,那是正的可接受极限,-2 ** 63是负的极限。)

对于指数,内部使用的不是 Python 数字;相反,它是一个 Py_ssize_t ,分别是 32/64 位机器上的带符号 32/64 位 int。所以,这就是看起来的硬性限制。

(如错误消息所述,int 和 intex 大小的整数 是两个不同的东西)

如果提供的输入在转换前大于 PY_SSIZE_T_MAXPy_ssize_t 的最大大小),则看起来也像 input() explicitly checks

if (len > PY_SSIZE_T_MAX) {
    PyErr_SetString(PyExc_OverflowError,
                    "input: input too long");
    result = NULL;
}

然后它将输入转换为 Python strPyUnicode_Decode.


为了让您正确看待这一点;如果每本书的平均长度为 500.000 个字符,而书籍总数的 estimation 约为 1.3 亿,那么理论上您可以 input 左右:

>>> ((2 ** 63) - 1) // 500000 * 130000000
141898

乘以这些字符;不过,这可能会花费您一些时间:-)(而且您首先会受到可用内存的限制!)

我们很容易通过实验找到答案。制作两个文件:

make_lines.py:

num_lines = 34

if __name__ == '__main__':
    for i in range(num_lines):
        print('a' * (2 ** i))

read_input.py:

from make_lines import num_lines

for i in range(num_lines):
    print(len(input()))

然后 运行 Linux 或 OSX 中的此命令(我不知道 Windows 等效项):

python make_lines.py | python3 read_input.py

在我的电脑上,它设法完成了,但到最后却很挣扎,显着减慢了其他进程。它打印的最后一件事是 8589934592,即 8 GiB。您可以根据您对时间和内存限制方面可接受的定义来找出适合自己的价值。