バージョン 2.1 で 新たに追加 された仕様です。
weakrefモジュールは、Pythonプログラマがオブジェクトへの 弱参照を作成できるようにします。
以下では、用語リファレント (referent) は弱参照が参照するオブジェクトを 意味します。
オブジェクトに対する弱参照は、そのオブジェクトを生かしておくのに 十分な条件にはなりません: あるリファレントに対する参照が弱参照しか 残っていない場合、ガベージコレクション機構は自由にリファレントを破壊し、 そのメモリを別の用途に再利用できます。弱参照の主な用途は、 巨大なオブジェクトを保持するキャッシュやマップ型の実装において、 キャッシュやマップ型にあるという理由だけオブジェクトを存続させたくない 場合です。 例えば、巨大なバイナリ画像のオブジェクトがたくさんあり、 それぞれに名前を関連付けたいとします。 Python の辞書型を使って 名前を画像に対応付けたり画像を名前に対応付けたりすると、 画像オブジェクトは辞書内のキーや値に使われているため存続しつづける ことになります。weakref モジュールが提供している WeakKeyDictionary や WeakValueDictionary クラスは その代用で、対応付けを構築するのに弱参照を使い、キャッシュや マップ型に存在するという理由だけでオブジェクトを存続させないように します。 例えば、もしある画像オブジェクトが WeakValueDictionary の 値になっていた場合、最後に残った画像オブジェクトへの参照を 弱参照マップ型が保持していれば、ガーベジコレクションはこのオブジェクトを 再利用でき、画像オブジェクトに対する弱参照内の対応付けはそのまま 削除されます。
WeakKeyDictionary や WeakValueDictionary は 弱参照を使って実装されていて、キーや値がガーベジコレクションによって回収された ことを弱参照辞書に知らせるような弱参照オブジェクトのコールバック関数を 設定しています。
ほとんどのプログラムが、いずれかの弱参照辞書型を使うだけで必要を満たせるはずです -- 自作の弱参照辞書を直接作成する必要は普通はありません。とはいえ、 弱参照辞書の実装に使われている低水準の機構は、高度な利用を行う際に恩恵を うけられるよう weakref モジュールで公開されています。
すべてのオブジェクトを弱参照できるわけではありません。 弱参照できるオブジェクトは、クラスインスタンス、(Cではなく) Pythonで書かれた関数、 (束縛および非束縛の両方の)メソッド、set および frozenset 型、ファイルオブジェクト、ジェネレータ、型オブジェクト、 bsddb モジュールの DBcursor 型、ソケット型、 array型、deque型、および正規表現パターンオブジェクト です。 バージョン 2.4 で 変更 された仕様: ファイル、ソケット、array、および正規表現 パターンのサポートを追加しました
list やdict など、いくつかの組み込み型は弱参照を 直接サポートしませんが、以下のようにサブクラス化を行えばサポートを 追加できます:
class Dict(dict): pass obj = Dict(red=1, green=2, blue=3) # this object is weak referencable
弱参照をサポートするために拡張型を簡単に作れます。 詳細については、3.3.3節 ``拡張型における弱参照''を読んでください。
object[, callback]) |
同じオブジェクトに対してたくさんの弱参照を作れます。 それぞれの弱参照に対して登録されたコールバックは、 もっとも新しく登録されたコールバックからもっとも古いものへと呼び出されます。
コールバックが発生させた例外は標準エラー出力に書き込まれますが、伝搬させられません。 それらはオブジェクトの__del__()メソッドが発生させる例外とまったく同様の 方法で処理されます。
objectがハッシュ可能ならば、弱参照はハッシュ可能です。それらはobjectが 削除された後でもそれらのハッシュ値を保持します。objectが削除されてから初めて hash()が呼び出された場合に、その呼び出しはTypeErrorを発生させます。
弱参照は等価性のテストをサポートしていますが、順序をサポートしていません。 参照がまだ生きているならば、callbackに関係なく二つの参照はそれらの リファレントと同じ等価関係を持ちます。リファレントのどちらか一方が削除された場合、 参照オブジェクトが同じオブジェクトである場合に限り、その参照は等価です。
バージョン 2.4 で 変更 された仕様: 以前はファクトリでしたが、サブクラス化可能な型になりました。 object 型から導出されています
object[, callback]) |
ProxyType
またはCallableProxyType
のどちらか一方の
型を持ちます。プロキシオブジェクトはリファレントに関係なくハッシュ可能ではありません。
これによって、それらの基本的な変更可能という性質に関係する多くの問題を避けています。
そして、辞書のキーとしてそれらの利用を妨げます。callbackはref()関数の
同じ名前のパラメータと同じものです。
object) |
object) |
[dict]) |
注意: 注意: WeakKeyDictionary は Python 辞書型の上に作られているので、 反復処理を行うときにはサイズ変更してはなりません。WeakKeyDictionary の場合、反復処理の最中にプログラムが行った操作が、(ガベージコレクションの副作用として) 「魔法のように」辞書内の要素を消し去ってしまうため、確実なサイズ変更は困難なのです。
[dict]) |
参考: