Skip to content
Advertisement

How to access Aʟʟ global variables in a function?

I’m trying to mimic the matlab load and save functions. I’m following this thread: Shelve Code gives KeyError

It is smart. However, if I write that code in a separate module, and try to import that module and invoke that function, then it can’t access the global variables.

Specifically, I write a happy.py and have the functions inside:

def save(filename='tmp', globals_=None):
    if globals_ is None:
        globals_ = globals()
        
    globals()
    import shelve
    my_shelf = shelve.open(filename, 'n')
    for key, value in globals_.items():
        if not key.startswith('__'):
            try:
                my_shelf[key] = value
            except Exception:
                print('ERROR shelving: "%s"' % key)
            else:
                print('shelved: "%s"' % key)
    my_shelf.close()

def load(filename='tmp', globals_=None):
    import shelve
    my_shelf = shelve.open(filename)
    for key in my_shelf:
        globals()[key] = my_shelf[key]
    my_shelf.close()

and when I try

a = 1
b = 2
happy.save()

It would not give save a and b.

Is this because global() would not give the objects outside the module? How can I do what I want to do then?

Advertisement

Answer

You can use inspect to look at the stack. This silly (poorly named function) that I’ve defined seems to do an OK job of picking up the global variables from the calling namespace although I haven’t tested it extensively. I am also unsure about whether it will work with different python implementations. (I mention this because the inspect.currentframe function is definitely implementation dependent). It seems to work OK with Cpython for what it’s worth.

import inspect
def save(globals=None):
    if globals is None:
        frames = inspect.stack()
        caller_frame = frames[-1][0]
        globals = dict((k,v) for (k,v) in caller_frame.f_globals.items() if not k.startswith('__'))
    return globals


if __name__ == "__main__":
    a = 1
    b = 2
    print save()
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement