考虑:
with open('test.txt', 'w') as f:
for i in range(5):
f.write("Line {}\n".format(i))
with open('test.txt', 'r') as f:
f.readline()
for line in f.readlines():
print(line.strip())
此输出
Line 1
Line 2
Line 3
Line 4
也就是说,f
有一个内部迭代器,f.readline()
消耗第一行,f.readlines()
读取所有内容其他行直到文件末尾。 从语言的角度来看,这是预期/保证的吗?
我找到的唯一信息来自docs.python.org ,
If you want to read all the lines of a file in a list you can also use
list(f)
orf.readlines()
.
我觉得这是模棱两可的。
最佳答案
当他们在文档中提到这个技巧时,他们并不期望您首先摆弄迭代器。
是的,这是预期的(并且很有用,例如当您想跳过标题行,然后阅读其余行时)。
如果您想确保读取所有行,只需在调用 readlines
之前倒回文件即可:
f.seek(0)
lines = f.readlines()
关于readlines
不倒回文件的文档有点缺乏。我做了很多谷歌搜索,这似乎是暗示和自然的。如果您仍然不相信,您必须查看源代码(来自 Python 3.6.1 源代码的 bytesio.c
):
static PyObject *
_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
{
Py_ssize_t maxsize, size, n;
PyObject *result, *line;
char *output;
CHECK_CLOSED(self);
if (PyLong_Check(arg)) {
maxsize = PyLong_AsSsize_t(arg);
if (maxsize == -1 && PyErr_Occurred())
return NULL;
}
else if (arg == Py_None) {
/* No size limit, by default. */
maxsize = -1;
}
else {
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
Py_TYPE(arg)->tp_name);
return NULL;
}
size = 0;
result = PyList_New(0);
if (!result)
return NULL;
output = PyBytes_AS_STRING(self->buf) + self->pos;
while ((n = scan_eol(self, -1)) != 0) {
self->pos += n;
我在 readline 循环开始后立即停止粘贴。在上面的行中,我们看到代码正在使用对象的当前 self->pos
值。并且在代码开头并没有重置。
关于python - readlines() 是否保证从当前位置而不是文件开头读取(在所有 Python 实现中)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42996434/