39

いくつかのコード:

import cStringIO

def f():
    buffer = cStringIO.StringIO()
    buffer.write('something')
    return buffer.getvalue()

ドキュメントには次のように書かれています。

StringIO.close():メモリバッファを解放します。閉じたStringIOオブジェクトを使用してさらに操作を実行しようとすると、ValueErrorが発生します。

やらなければならないのですかbuffer.close()、それともバッファがスコープ外になり、ガベージコレクションが行われると自動的に発生しますか?

アップデート:

私はテストをしました:

import StringIO, weakref

def handler(ref):
    print 'Buffer died!'

def f():
    buffer = StringIO.StringIO()
    ref = weakref.ref(buffer, handler)
    buffer.write('something')
    return buffer.getvalue()

print 'before f()'
f()
print 'after f()'

結果:

vic@wic:~/projects$ python test.py 
before f()
Buffer died!
after f()
vic@wic:~/projects$
4

4 に答える 4

19

特別な状況では予期しない動作が発生する可能性があるため、通常はステートメントを呼び出すclose()か使用することをお勧めします。withたとえば、エクスパットIncrementalParserはファイルが閉じられることを期待しているようです。または、まれな状況でタイムアウトが発生するまで、解析されたxmlの最後の一口を返しません。

ただしwith、クロージングを処理する-statementの場合は、 Ivcのコメントに記載されているように、-ModulesのStringIOクラスを使用する必要があります。io

これは、StringIOを手動で閉じることで解決した従来のsax-parserスクリプトの大きな頭痛の種でした。

「範囲外」のクローズは機能しませんでした。タイムアウト制限を待っただけです。

于 2012-03-15T11:56:41.283 に答える
17

ソースから:

class StringIO:
    ...
    def close(self):
        """Free the memory buffer.
        """
        if not self.closed:
            self.closed = True
            del self.buf, self.pos

したがってStringIO.close、メモリバッファを解放して、およびへの参照を削除しStringIO.bufますStringIO.pos。ただし、selfがガベージコレクションの場合、その属性もガベージコレクションになり、と同じ効果がありStringIO.closeます。

于 2013-08-23T09:01:37.987 に答える
9

StringIO.close()これは、ファイルのように取得し、最終的にそれらを閉じようとするルーチンにとって便利なだけです。自分で行う必要はありません。

于 2012-03-15T11:50:07.503 に答える
2

私はtryそれを処理するためにブロックを使用して終了しました。

import cStringIO

def f():
    buffer = cStringIO.StringIO()
    try:
        buffer.write('something')
        return buffer.getvalue()
    finally:
        buffer.close()
于 2014-04-08T17:21:51.007 に答える