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()は、関数の外部で呼び出されると正しい結果が得られますが、関数で同じ関数を呼び出そうとすると、値0にfoo()なる空のリストが生成len(lst())されます。最後の2行にコメントを付けてみましたが、それでも空のリストが返されます。上記のコードの何が問題になっていますか?

4

4 に答える 4

7

ファイルオブジェクトは、一度だけ読み取ることを目的としています。一度実行finread()れると、ファイルはすでにに到達しているため、ファイルから他のものを読み取ることはできなくなりますEOF

ファイルの内容を読み取るには、f.read(size)を呼び出します。これにより、ある量のデータが読み取られ、文字列として返されます。sizeはオプションの数値引数です。サイズが省略または負の場合、ファイルの内容全体が読み取られて返されます。ファイルがマシンのメモリの2倍の大きさである場合、それはあなたの問題です。それ以外の場合は、最大サイズのバイトが読み取られて返されます。ファイルの終わりに達した場合、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()
''

つまり、ファイルの終わりに到達しました。ここには 3 つの選択肢があります。

  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)

ここで何をしようとしているのかは明確ではありませんが、予約されたキーワードであるため、変数名としてlst()使用せずに、から格納された戻り値を使用する方がよいでしょう。in

何かのようなもの:

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

ファイル オブジェクトは 1 回しか読み取るfin.read()ことができません。つまり、後で呼び出す前に fin.read() を呼び出すと、何も返されません。

これを修正するfin.seek(0)には、fin.read() を呼び出した後に呼び出すか、ファイルをバッファに読み込みます。

于 2012-05-27T11:58:59.573 に答える