Ответ 1
Необязательный аргумент должен означать, сколько (приблизительно) байтов считывается из файла. Файл будет считан далее, пока не закончится текущая строка:
readlines([size]) -> list of strings, each a line from the file.
Call readline() repeatedly and return a list of the lines so read.
The optional size argument, if given, is an approximate bound on the
total number of bytes in the lines returned.
Другая цитата:
Если задан необязательный параметр sizehint, он считывает много байтов из файла и достаточно больше для завершения строки и возвращает строки из этого.
Вы правы, что это мало что делает для небольших файлов, что интересно:
In [1]: open('hello').readlines()
Out[1]: ['Hello\n', 'there\n', '!\n']
In [2]: open('hello').readlines(2)
Out[2]: ['Hello\n', 'there\n', '!\n']
Можно подумать, что это объясняется следующей фразой в документации:
Прочитайте до EOF с помощью readline() и верните список, содержащий прочитанные строки. Если присутствует необязательный аргумент sizehint, вместо чтения до EOF читаются целые строки, содержащие приблизительно sizehint байты (возможно, после округления до размера внутреннего буфера). Объекты, реализующие файловый интерфейс, могут игнорировать параметр sizehint, если он не может быть реализован или не может быть эффективно реализован.
Однако, даже когда я пытаюсь читать файл без буферизации, он ничего не меняет, а это означает, что подразумевается какой-то другой внутренний буфер:
In [4]: open('hello', 'r', 0).readlines(2)
Out[4]: ['Hello\n', 'there\n', '!\n']
В моей системе размер этого внутреннего буфера составляет около 5 килобайт /1,7 тыс. строк:
In [1]: len(open('hello', 'r', 0).readlines(5))
Out[1]: 1756
In [2]: len(open('hello', 'r', 0).readlines())
Out[2]: 28080