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 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:
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 existing function signatures:
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 purposes. A similar technique is even used in stdlib logging, here, so that loggers are able to discover the source code/file name/line number/function name without needing to be explicitly passed that context. However, in normal use cases, it would not usually be a sensible design decision to access stack frames in the case that B.func actually needed to use A, because it's cleaner and easier to pass along the information that you need rather than to try and "reach back" to a caller.
inspect.currentframe is an implementation detail).currentframe() is alluding to Stackless ( not to Jython or Iron Python )....can anyone confirm this?pdb. suppose you are in ipython, and you get an unhandled exception in B.func. then you can use the magic %debug and you're in the body of func. from there you have the full power of the interpreter, and you could type import inspect and do whatever introspection might help you. just because a tool can be abused it doesn't mean it should never be usedYou pass it to b.func() as an argument.
b.func() really has no business knowing who called itDo this by refactoring your code to work like
class A(): def go(self): b = B(self) b.func() class B(): def __init__(self, a): self.a = a def func(self): # Use self.a or
class A(): def go(self): b = B() b.func(self) class B(): def func(self, a): # a As that may call B's instance. I wouldn't like to keep them all in B's instanceI agree with Benjamin - pass it to b.func() as an argument and don't introspect it!!!!
If your life really depends on it, then I think you can deduce the answer from this answer.
objectrather than nothing so that you are using new-style classes.