Categories: Python

【Python】参照先のオブジェクトが削除されると消える参照【弱参照】

この記事では、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で弱参照を使う方法を解説しました。

弱参照を使うことでオブジェクトを色々なところで参照しても管理は大元のみで行うことができるようになります。

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ

ゆうまる

独学でプログラミングを勉強しているおじさん。いろんな言語を勉強したが浅く広くなためあまり仕事につながらない。また忘れっぽいため自分のブログを備忘録としても使っている。産まれてこのかたずっとネコを飼ってる生粋のネコ派。最近お腹が出てきて筋トレに奮闘中!

View Comments

Recent Posts

【Dart】コンストラクタのデフォルト引数について

Dartのコンストラクタのデフォルト引数…

2週間 ago

【Unity】有料アセットを無料で手に入れる方法

この記事では、Unityの有料アセットを…

4か月 ago

【Python】任意の秒数だけ処理を一時停止する方法【sleep()関数】

この記事では、Pythonで任意の秒数だ…

1年 ago

【Python】Wordの文書の新規作成と読み書き

この記事では、Pythonを使ってWor…

1年 ago

【Python】メタクラスって結局なんなの?

この記事では、Pythonのメタクラスに…

1年 ago