When you create something like a collection of classes in Python, you may want to have a reference to the parent object.
In such a case, in other languages, it is sometimes said that a variable called ʻowner` is created to have a reference to the parent object, but if it is implemented as it is, it becomes a circular reference, and the acquired memory was intended. It may not be released at the timing.
Code where circular references can occur
class ParentClass:
def __init__(self):
self.child = []
class ChildClass:
def __init__(self, owner):
self._owner = owner
p = ParentClass()
p.child.append(ChildClass(p))
# ...
For this case, there is a ** weak reference (weakref module) ** that does not increment the reference counter when referencing an object.
Code with weak references
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))
# ...
If you want to follow the reference created by this weakref object, call it with () like a method.
Code with weak references
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()
# ...