3
fin = open('/abc/xyz/test.txt', 'a+')

def lst():
  return fin.read().splitlines()

print lst()

def foo(in):
  print lst()
  fin.write(str(len(lst()) + in)
  fin.flush()

在上面的代码中,当print lst()在函数外部调用时,它会给出正确的结果,但是当尝试在函数中调用相同的函数时,foo()它会产生空列表,其len(lst())值为 0。我还尝试通过注释最后两行,但它仍然返回空列表。上面的代码有什么问题?

4

4 回答 4

7

文件对象应该被读取一次。一旦fin已经read()到达,您就不能再从文件中读取任何其他内容,因为它已经到达EOF

要读取文件的内容,请调用 f.read(size),它会读取一定数量的数据并将其作为字符串返回。size 是一个可选的数字参数。当 size 省略或为负时,将读取并返回文件的全部内容;如果文件是机器内存的两倍,那是你的问题。否则,最多读取并返回 size 个字节。如果已到达文件末尾,f.read() 将返回一个空字符串 ("")。

http://docs.python.org/tutorial/inputoutput.html#methods-of-file-objects

如果您确实需要可重入访问您的文件,请使用:

def lst():
  fin.seek(0)
  return fin.readlines()
于 2012-05-27T09:32:04.927 回答
5

将完整的文件读入内存后,从该文件中读取更多内容将导致返回一个空字符串:

>>> example = open('foobar.txt')
>>> example.read()
'Foo Bar\n'
>>> example.read()
''

换句话说,您已经到达文件的末尾。您在这里有三个选择:

  1. 每次完整读取时重新打开文件。
  2. 使用.seek()再次转到文件的开头:

    >>> example = open('foobar.txt')
    >>> example.read()
    'Foo Bar\n'
    >>> example.seek(0)
    >>> example.read()
    'Foo Bar\n'
    
  3. 将文件的内容存储在变量中,从而将其缓存在内存中,然后使用它而不是重新读取文件。

于 2012-05-27T09:35:51.177 回答
3

read()一旦你打过电话,fin就已经读过了。

如果您想read()再次使用它(在第一次尝试时丢弃了内容),您需要重新open()seek()文件的开头。

我建议您在 中执行此操作lst(),或者更好的是,将返回的内容存储在lst()

除此之外...

fin.write(str(len(lst()) + in)

目前尚不清楚您要在这里做什么,但是最好使用存储的返回值 fromlst()而不是in用作变量名,因为它是一个保留关键字

就像是:

lines = lst()
# [...]
number_of_lines = len(lines)
fin.write(str(number_of_lines) + some_other_str)
于 2012-05-27T09:33:24.990 回答
1

文件对象只能读取一次,这意味着如果fin.read()您在后面的 fin.read() 之前调用过,则不会返回任何内容。

fin.seek(0)通过调用 fin.read() 后调用来修复此问题,或将文件读取到某个缓冲区。

于 2012-05-27T11:58:59.573 回答