4

Suppose I have a free function which has been called from a class method. Is there a way for me to introspect the call stack in the free function and determine what object called me?

def foo(arg1) :
  s = ? #Introspect call stack and determine what object called me
  # Do something with s

Thanks!

MK.
  • 3,907
  • 5
  • 34
  • 46
  • Check this http://stackoverflow.com/questions/132058/getting-stack-trace-from-a-running-python-application For your scenario I would recommend using http://docs.python.org/library/traceback.html – CriGoT Jul 13 '10 at 15:29
  • 1
    Wouldn't it be simpler to make `foo` part of a class and remove all doubt about the object invoking the method? – S.Lott Jul 13 '10 at 15:36
  • I am also very curious to know why it would be needed ? why can't u just pass the calling object as argument? – Anurag Uniyal Jul 13 '10 at 16:15
  • 1
    Doing this is a horrible, horrible idea. You're trying to defeat one of the core principles of structured programming. – Jochen Ritzel Jul 13 '10 at 16:46
  • Agreed, add another parameter to foo which passes in the object that called it. – David C Feb 05 '13 at 21:19

1 Answers1

2

There isn't really the concept of "a calling object". You can introspect the stack and find if your calling function has a first argument named self, I guess -- if you're called directly from a normally-coded instance method (absolutely not a class method as you say... I imagine you're just horribly mis-speaking, because the very purpose of a classmethod is to not have "an object", i.e. an instance, involved!-), that should detect that.

The inspect module offers you the tools for advanced introspection (recommended only for debugging and development purposes, never for "actual production use"!!!). However, note that even tracing the function is not trivial: you get stack frames which point to the code object (which doesn't point back to the function).

Still, it can be arranged, because there are pseudo-dicts of local variables also pointed from stack frames, and arguments are local variables, so what you're looking for is an entry in the local variables of your caller's stack frame that is named self (and in addition of course you need a lot of optimism and a smidgeon of luck as nobody forces your caller to be coded sensibly -- the argument normally named self could be named otherwise, and then you're in trouble;-).

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395