この記事では、Pythonで弱参照を使う方法を解説します。
弱参照とは、ガベージコレクタから参照していると思われない参照のことを言います。
オブジェクトの参照が弱参照のみになった場合、そのオブジェクトは削除してもよいオブジェクトとしてガベージコレクタに認識されます。
それでは、弱参照の使い方を見ていきましょう!
弱参照の使い方
弱参照は、weakref
モジュールを使うことで簡単に扱うことができます。weakref
モジュールは、標準ライブラリなのでインポートするだけで使用可能です。
import weakref
弱参照をサポートしている型は、ユーザー定義型かサブクラス化したリストや辞書です。
# ユーザー定義型
class クラス名:
pass
# 辞書のサブクラス
class Dict(dict):
pass
オブジェクトの弱参照を返すにはweakref.ref(object[, callback])
を使います。
import weakref
# 簡単なクラス
class MyClass:
def __init__(self, value):
self.value = value
# インスタンス化
mc = MyClass('mcです')
# 弱参照の生成
ref = weakref.ref(mc)
print(ref().value)
# 参照元のオブジェクト削除
del mc
print(ref().value)
実行結果
mcです
Traceback (most recent call last):
File "main.py", line 18, in
print(ref().value)
AttributeError: 'NoneType' object has no attribute 'value'
weakref.ref()
は、参照を返しているので呼び出すには()
が必要となります。
callback
引数に関数を指定することでオブジェクトが削除された時に指定した関数を呼び出すことができます。指定した関数の引数には、その弱参照オブジェクトが渡されます。
import weakref
class MyClass:
pass
mc = MyClass()
# callbackを指定
ref = weakref.ref(mc, print)
print('del 開始')
del mc
print('del 終了')
実行結果
del 開始
<weakref at 0x7fa450a299f0; dead>
del 終了
弱参照オブジェクトは、参照先が消えている場合にNone
を返します。
import weakref
class MyClass:
pass
mc = MyClass()
ref = weakref.ref(mc)
del mc
if ref():
print('参照先が存在します')
else:
print('参照先が存在しません')
実行結果
参照先が存在しません
key・valueを弱参照する辞書
辞書のkey
を弱参照するにはWeakKeyDictionary([dict])
、value
を弱参照とするにはWeakValueDictionary([dict])
を使います。
WeakKeyDictionary([dict]) | key を弱参照する辞書 |
---|---|
WeakValueDictionary([dict]) | value を弱参照する辞書 |
以下のコードは、WeakValueDictionary([dict])
を使ってvalueを弱参照しただけです。
import weakref
# 簡単なクラス
class MyClass:
def __init__(self, value):
self.value = value
# インスタンス化
mc = MyClass('mcです')
# 弱参照の生成
ref = weakref.WeakValueDictionary({'mc': mc})
print(ref['mc'].value)
# 参照先のオブジェクト削除
del mc
print(ref['mc'].value)
実行結果
mcです
Traceback (most recent call last):
File "main.py", line 18, in <module>
print(ref['mc'].value)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/weakref.py", line 134, in __getitem__
o = self.data[key]()
KeyError: 'mc'
まとめ
この記事では、Pythonで弱参照を使う方法を解説しました。
弱参照を使うことでオブジェクトを色々なところで参照しても管理は大元のみで行うことができるようになります。
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ