2013-02-24 1 views
1

из doc:Что означает io.IOBase.readlines (hint) в python?

readlines(hint=-1) 
    Read and return a list of lines from the stream. 
    hint can be specified to control the number of lines read: 
     no more lines will be read if the total size (in bytes/characters) of all lines so far exceeds hint. 

Что истинный смысл намека?

В некоторых окружающих средах:

python3 -c 'from io import StringIO;print(StringIO(u"hello\n"*10).readlines(6));import sys;print(sys.version_info[0:3])' 
['hello\n', 'hello\n'] 
(3, 3, 0) 

python -c 'from io import StringIO;print(StringIO(u"hello\n"*10).readlines(6));import sys;print(sys.version_info[0:3])' 
[u'hello\n', u'hello\n'] 
(2, 7, 2) 

python -c 'from io import StringIO;print(StringIO(u"hello\n"*10).readlines(6));import sys;print(sys.version_info[0:3])' 
[u'hello\n'] 
(2, 6, 6) 

Почему более 6 символов?

Some one said that depended on buffer size.

Но в моей машине я не могу отключить текстовый ввод-вывод.

>>> import sys 
>>> sys.version 
'3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 01:25:11) \n[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]' 
>>> open('/etc/hosts','r',3).readlines(3) 
['##\n', '# Host Database\n'] 
>>> open('/etc/hosts','r',0).readlines(3) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: can't have unbuffered text I/O 
>>> 

Или это ошибка в этом методе?


2013/02/25 Обновлено:

Я проверить source (из питона 2,6/2,7/3.x), но я не могу это объяснить:

def readlines(self, hint=None): 
    """Return a list of lines from the stream. 

    hint can be specified to control the number of lines read: no more 
    lines will be read if the total size (in bytes/characters) of all 
    lines so far exceeds hint. 
    """ 
    if hint is None or hint <= 0: 
     return list(self) 
    n = 0 
    lines = [] 
    for line in self: 
     lines.append(line) 
     n += len(line) 
     if n >= hint: 
      break 
    return lines 

ответ

0

Я нашел отличия от StringIO и BytesIO (Но я понятия не имею, почему):

Первый чек это (питон 2,7/3.3):

Python 2.7.2 (default, Jun 20 2012, 16:23:33) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from io import BytesIO,StringIO 
>>> print(BytesIO(b'hello\n'*10).readlines(6)) 
['hello\n'] 
>>> print(StringIO(u'hello\n'*10).readlines(6)) 
[u'hello\n', u'hello\n'] 
>>> 

Исходные коды C от StringIO и BytesIO ссылке здесь:

Modules/_io/iobase.c#l591

620  while (1) { 
621   PyObject *line = PyIter_Next(self); 
622   if (line == NULL) { 
623    if (PyErr_Occurred()) { 
624     Py_DECREF(result); 
625     return NULL; 
626    } 
627    else 
628     break; /* StopIteration raised */ 
629   } 
630 
631   if (PyList_Append(result, line) < 0) { 
632    Py_DECREF(line); 
633    Py_DECREF(result); 
634    return NULL; 
635   } 
636   length += PyObject_Size(line); 
637   Py_DECREF(line); 
638 
639   if (length > hint) 
640    break; 
641  } 

Modules/_io/bytesio.c#l380

413  while ((n = get_line(self, &output)) != 0) { 
414   line = PyBytes_FromStringAndSize(output, n); 
415   if (!line) 
416    goto on_error; 
417   if (PyList_Append(result, line) == -1) { 
418    Py_DECREF(line); 
419    goto on_error; 
420   } 
421   Py_DECREF(line); 
422   size += n; 
423   if (maxsize > 0 && size >= maxsize) 
424    break; 
425  } 
426  return result; 
+1

Я думаю, что разница между условиями 'length> hint' и' size> = maxsize'. Один останавливается только тогда, когда количество прочитанных строго превышает запрашиваемую сумму, тогда как другая будет остановлена, если сумма будет точно удалена. – Blckknght

0

Это документально, следовательно, не является ошибкой:

buffering - необязательное целое число, используемое для установки политики буферизации. Pass 0 для переключения буферного от (разрешено только в двоичном режиме), 1 на линии выбора буферизации (использоваться только в текстовом режиме), и целое число>1 , чтобы указать размер буфера отрезка фиксированного размера.

Чтобы ответить на вопрос: «Почему более 6 символов?»

Это также задокументированы: readlines всегда возвращает полные строки:

намек может быть определен, чтобы контролировать количество прочитанных строк: не более линии будут читаться если общий размер (в байтах/символов) всех линий до сих пор превышает намек.

Это означает: прочитайте еще вся строка; если total read size>hint, затем прекратите чтение.

В вашем примере после прочтения первого "hello" размер еще не увеличен, поэтому читается вторая строка.

+0

'Привет' + '\ п '- шесть символов. Между python 2.6 и python 2.7/3.x существует что-то другое. – imxylz

+0

@imxylz Это 6, который не _exceed_ размером 6 :) Да, в Python 2.6 что-то другое, но в документах сказано «суммарно приблизительно размерные байты», поэтому это не гарантирует точности. –

+0

Пожалуйста, проверьте источник: http://hg.python.org/cpython/file/96f08a22f562/Lib/_pyio.py#l505 – imxylz