Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Introspect calling object

How do I introspect A's instance from within b.func() (i.e. A's instance's self):

class A():
    def go(self):
        b=B()
        b.func()

class B():
    def func(self):
        # Introspect to find the calling A instance here
like image 762
Jonathan Livni Avatar asked Sep 01 '11 15:09

Jonathan Livni


People also ask

What is object introspection?

In computer programming, introspection is the ability to determine the type of an object at runtime. It is one of Python's strengths. Everything in Python is an object and we can examine those objects.

What does calling object mean?

"calling object" means the object that is calling method . "called object" means the object on which method acts.

What is inspect stack?

inspect. stack() returns a list with frame records. In function whoami() : inspect. stack()[1] is the frame record of the function that calls whoami , like foo() and bar() . The fourth element of the frame record ( inspect.


2 Answers

In general we don't want that func to have access back to the calling instance of A because this breaks encapsulation. Inside of b.func you should have access to any args and kwargs passed, the state/attributes of the instance b (via self here), and any globals hanging around.

If you want to know about a calling object, the valid ways are:

  1. Pass the calling object in as an argument to the function
  2. Explicitly add a handle to the caller onto b instance sometime before using func, and then access that handle through self.

However, with that disclaimer out of the way, it's still worth knowing that python's introspection capabilities are powerful enough to access the caller module in some cases. In the CPython implementation, here is how you could access the calling A instance without changing your interfaces:

class A():
    def go(self):
        b=B()
        b.func()

class B():
    def func(self):
        import inspect
        print inspect.currentframe().f_back.f_locals['self']

if __name__ == '__main__':
    a = A()
    a.go()

Output:

<__main__.A instance at 0x15bd9e0>

This might be a useful trick to know about for debugging code sometimes. But it would not be a sensible design decision to ever access the stack frames like this in the case that B.func actually needed to use A for any reason.

like image 98
wim Avatar answered Sep 30 '22 20:09

wim


You pass it to b.func() as an argument.

like image 45
Benjamin Peterson Avatar answered Sep 30 '22 21:09

Benjamin Peterson