2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

弱参照を使う

Posted at

Pythonでなんらかのクラスのコレクションのようなものを作るとき、親になっているオブジェクトの参照を持っておきたい ということはあると思います。

そんなとき、他の言語などだとときどき、ownerという変数を作って親オブジェクトの参照を持っておく などと言うことがあるのですが、そのまま実装すると循環参照となり、取得したメモリが意図したタイミングで解放されなくなることがあります。

循環参照が起こりうるコード
class ParentClass:
  def __init__(self):
    self.child = []

class ChildClass:
  def __init__(self, owner):
    self._owner = owner

p = ParentClass()
p.child.append(ChildClass(p))
# ... 

こんなときのために、オブジェクトを参照する際に参照カウンタを増やさない、**弱参照(weakrefモジュール)**というものがあります。

弱参照を使ったコード
import weakref

class ParentClass:
  def __init__(self):
    self.child = []

class ChildClass:
  def __init__(self, owner):
    self._owner = weakref.ref(owner)

p = ParentClass()
p.child.append(ChildClass(p))
# ... 

なお、このweakrefオブジェクトで作った参照を辿りたいときは、メソッドのように()をつけて呼び出します。

弱参照を使ったコード
import weakref

class ParentClass:
  def __init__(self):
    self.child = []

  def message(self):
    print("called")

class ChildClass:
  def __init__(self, owner):
    self._owner = weakref.ref(owner)

  def message(self): 
    self._owner().message()

p = ParentClass()
p.child.append(ChildClass(p))
p.child[0].message()
# ... 
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?