3

透かしまたはオブジェクトのファイナライズのイベントで(永続ストレージに)フラッシュするトランザクションのキャッシュを保持します。__del__すべてのオブジェクトで呼び出されることが保証されなくなったので、同様の関数(または__del__それ自体)をatexit.register(初期化中に)フックする適切なアプローチはありますか?

私が間違っていなければ、これにより、メソッドがバインドされているオブジェクトがプログラムが終了するまでぶらぶらします。これは問題になる可能性は低いですが、もっとエレガントな解決策があるのではないでしょうか。

注:キャッチできない例外が発生する可能性がある__del__ため、使用が理想的ではないことはわかっていますが、プログラム全体でカスケード呼び出しを行わないで、これを行う別の方法を考えることはできません。TIA!finalize()

4

5 に答える 5

4

close()リソースを処理する必要がある場合は、またはfinalize()メソッドを明示的に呼び出すことをお勧めします 。withそれを抽象化するステートメントを見てください。あなたの場合、weakrefモジュールはオプションかもしれません。キャッシュされたオブジェクトは、システムによってガベージ コレクションされ、その__del__()メソッドが呼び出されるか、まだ生きている場合はそれらをファイナライズすることができます。

于 2008-12-23T05:10:35.403 に答える
3

デフォルトで 2.5 および 2.6 にある をatexit使用して表現できるようにコードをリファクタリングできるかどうかを確認するか、試してみます。2.5 には、物事を少し単純化するモジュール contextlib が含まれています。Canonical の Storm ORM を使用するとき、私はこのようなことをしました。with_statement__future__

from future import with_statement

@contextlib.contextmanager
def start_transaction(db):
  db.start()
  yield
  db.end()

with start_transaction(db) as transaction:
  ...

db 以外の場合は、フラッシュするオブジェクトをグローバルに登録してから、同様のものを使用できます。このアプローチの利点は、物事を明確に保つことです。

于 2008-12-23T14:21:43.777 に答える
2

というファイルに以下を入れます。destructor.py

import atexit

objects = []

def _destructor():
    global objects
    for obj in objects:
        obj.destroy()
    del objects

atexit.register(_destructor)

次のように使用します。

import destructor

class MyObj(object):
    def __init__(self):
        destructor.objects.append(self)
        # ... other init stuff
    def destroy(self):
        # clean up resources here
于 2008-12-23T10:46:14.743 に答える
2

フラッシュを実行するときにオブジェクトが生きている必要がない場合は、弱い参照を使用できます

これは提案されたソリューションに似ていますが、実際の参照を使用するのではなく、フラッシュを実行するコールバック関数を使用して弱い参照のリストを保存します。この方法では、参照によってこれらのオブジェクトが存続することはなく、__del__メソッドで循環ガベージの問題が発生することもありません。

特定の時点で確実に行われる必要がある場合は、終了時に弱い参照のリストを実行して、まだ生きているものを手動でフラッシュできます。

于 2008-12-23T21:52:16.927 に答える
0

atexitここに行く方法だと思います。

于 2008-12-23T06:51:34.653 に答える