Getting container/parent object from within python Getting container/parent object from within python python python

Getting container/parent object from within python


Pass a reference to the Bar object, like so:

class Foo(object):    def __init__(self):        self.text = "Hello World"  # has to be created first, so Bar.__init__ can reference it        self.bar = Bar(self)class Bar(object):    def __init__(self, parent):        self.parent = parent        self.newText = parent.textfoo = Foo()

Edit: as pointed out by @thomleo, this can cause problems with garbage collection. The suggested solution is laid out at http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python/ and looks like

import weakrefclass Foo(object):    def __init__(self):        self.text = "Hello World"        self.bar = Bar(self)class Bar(object):    def __init__(self, parent):        self.parent = weakref.ref(parent)    # <= garbage-collector safe!        self.newText = parent.textfoo = Foo()


is it possible to get the object, say Foo, that contains another object, Bar, from within Bar itself?

Not "automatically", because the language isn't built like that, and in particular, the language is built such that there is no way to guarantee that Foo exists.

That said, you can always do it explicitly. Attributes, like every other identifier in Python, are just names, not storage space for data; so nothing prevents you from letting the Bar instance have a manually assigned foo attribute that is a Foo instance, and vice-versa at the same time.


Yes, it's possible. Even without passing the container reference on object creation, i.e. if your object is a class attribute.Your object needs to implement the descriptor protocol (have a __get__()):

class ChildName(SimpleNamespace):                                                             def __get__(self, instance, owner):        # instance is our parent        return f'I am {self.name}, my parent is {instance.name}.'class ChildDiff(SimpleNamespace):    @property    def diff(self):        return self.born - self.parent.born    def age_diff(self):        return f'I am {self.diff} years older than {self.parent.name}.'    def __get__(self, instance, owner):        self.parent = instance  # XXX: weakref?        return self  # expose object to be able call age_diff() etc.class Parent(SimpleNamespace):    child_name = ChildName(name='Bar')    child_diff = ChildDiff(born=42)parent = Parent(name='Foo', born=23)print(parent.child_name)             # ... I am Bar, my parent is Foo.print(parent.child_diff.age_diff())  # ... I am 19 years older than Foo.