8

I know this is something one normally should not do, and I know the reasons for it. However, I am making a debugging function within a class that should display some information about the module that called it.

I need to know how to go up one level in the name space to find a variable that should always exist in a program that both calls this module and needs this function.

I know one can get the main name space with:

    import __main__

But I'm guessing that this includes everything from the very first launched module onward, and I just want the one that called this one.

Kelketek
  • 2,406
  • 5
  • 21
  • 28

3 Answers3

2

Try using Python interpreter stack

warvariuc
  • 57,116
  • 41
  • 173
  • 227
  • I eventually found a way to do what I wanted without going up the name space, but this is most likely what would be needed should I have not found a way, so I'm selecting it as the answer. – Kelketek Mar 23 '12 at 12:51
1

warvariuc already answered but an example could be great too. If you want to be aware of the previous namespace, you can use inspect:

import inspect
from pprint import pprint


def foo():
    frame = inspect.currentframe()
    previous_namespace = frame.f_back.f_locals
    pprint(previous_namespace)


def bar():
    def inner_function():
        pass
    a = "foo"
    b = 5
    c = {}
    d = []

    foo()

Then you can do:

>>> bar()

{'a': 'foo',
 'b': 5,
 'c': {},
 'd': [],
 'inner_function': <function bar.<locals>.inner_function at 0x0000000002D6D378>}
snoob dogg
  • 2,491
  • 3
  • 31
  • 54
1

The object that calls the 'debugging object' should just pass self as a parameter. Then the 'debugging object' will have access to all the callers attributes. For example:

class Custom(object):
    def __init__(self):
        self.detail = 77

    def call_bug(self, name):
        name.bug(self)

class Debugger(object):
    def bug(self, caller):
        print caller.__dict__

custom = Custom()
debugger = Debugger()
custom.call_bug(debugger)

output:
{'detail': 77}

This principle will work fine across different files.

fraxel
  • 34,470
  • 11
  • 98
  • 102
  • Not quite what I mean. This is to get the display from __repr__ working, so I can't really modify how it invokes the function. I can only have said function grab outward. The __repr__ output needs to change depending on the function that calls it. Er, that's two underscores, then repr, then two more underscores. It's not formatting correctly here. It's the string used to represent an object when it's printed inside of a list. – Kelketek Mar 23 '12 at 11:09
  • 1
    @Kelketek - ah I see. I think you need to use the `inspect` module. This allows you to look at live objects and their attributes, it also allows you to traverse backwards and find caller objects/namespace. `inspect.getframeinfo(inspect.currentframe().f_back.f_back)` – fraxel Mar 23 '12 at 11:44