3

Python ガベージ コレクターがどのように機能するか、オブジェクトがいつ収集されるかを制御するためにできることがあるかどうかを理解しようとしています。私はこのテストを書きました:

>>> class Test:
...     def __del__(self):
...         print 'Delete ' + str(self)
...
>>> def fun():
...    return Test()
...
>>> fun()
<__main__.Test instance at 0x0000000002989E48>
>>> fun()
Delete <__main__.Test instance at 0x0000000002989E48>
<__main__.Test instance at 0x00000000023E2488>
>>> fun()
Delete <__main__.Test instance at 0x00000000023E2488>
<__main__.Test instance at 0x0000000002989C48>

ご覧のとおりTest、インスタンスを保持していませんが、次に を呼び出すまでインスタンスは削除されませんfunfunこれは単なる事故ですか (他の時点で削除された可能性があります)、それとも再度電話をかけたときにのみ削除される特定の理由がありますか? 参照を保持しない場合、確実に削除されるようにするためにできることはありますか?

4

2 に答える 2

2

del戻り値を明示的に呼び出してみてください。

returned_value = fun()
del returned_value

しかし、ファイナライザーのようなもの__del__は問題になる可能性があります。既に見てきたように、問題の 1 つは、それらがいつ呼び出されるかが決定論的ではないということです。また、ファイナライザ内で、削除されたオブジェクトを再インスタンス化することもできます。たとえば、グローバル リストにオブジェクトへの参照を貼り付けます。

withロックのロック解除、ファイルのクローズ、データベース接続の解放など、リソースを解放する必要がある場合 (生のメモリだけではありません)、コンテキスト マネージャーを使用し、ステートメントを使用してその寿命を制限します。これらのリソースの多くは、すでにコンテキスト マネージャーです。たとえば、 threading.Lock は、次を使用して暗黙的にロックおよびロック解除できますwith

# "with" statement will call the __enter__ method of self.lock,
# which will block until self.lock can be locked
with self.lock:
    # do thread-synchronized stuff here

# self.lock is automatically released here - at then end of
# the "with" block, the lock's __exit__ method is called, which
# releases the lock. This will get called even if the block is 
# exited by a raised exception
于 2013-07-14T14:31:31.437 に答える