web-dev-qa-db-ja.com

StringIO.close()を実行する必要がありますか?

いくつかのコード:

_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$
_
27
warvariuc

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

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

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

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

14
Don Question

ソースから:

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と同じ効果があります。

11
warvariuc

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

tryブロックを使用して処理しました。

import cStringIO

def f():
    buffer = cStringIO.StringIO()
    try:
        buffer.write('something')
        return buffer.getvalue()
    finally:
        buffer.close()
3
DrRobotNinja