2

I am trying to call globals() inside a function imported from another file, to retrieve the globally defined values of the program.

However, the dictionary it gives is different from the dictionary when called outside of the function.

I know this is meant to happen since here it says:

The globals table dictionary is the dictionary of the current module (inside a function, this is a module where it is defined, not the module where it is called).

But is there any trick, or another function, which makes globals() behave as if it were called in __main__?

This problem can be recreated easily. For example, in foo.py put:

def get_globals():
    return globals()

Then in the main program:

from foo import get_globals()

main_globals = globals()

foo_globals = get_globals()

main_globals == foo_globals
Out [1]: False

However, is there any way to get this last line to read:

main_globals == foo_globals
Out [2]: True

Thank you in advance for the help :)

Aldahunter
  • 618
  • 1
  • 6
  • 12
  • 3
    1) This is almost always a bad idea. 2) Why `__main__`'s globals? What if you call it from within a module you're writing and you want that module's globals? – user2357112 Apr 17 '19 at 02:23
  • 3
    Really, you should probably use some other way of communicating information between parts of your program. Probably function arguments and return values. – user2357112 Apr 17 '19 at 02:24
  • 1
    I agree with the previous comments. You can twist your arm backwards trying very fancy stuff when very elementary solutions exist. Keep it simple. It’s very rare that you have to dip into such complex solutions. Read the zen of python. – polarise Apr 17 '19 at 03:17
  • 1
    You're attempting to update your local namespace with everything from another namespace. That's extremely volatile; if anything changes in the other NS, this local NS will change as well, both making your local functionality's dependencies opaque and likely polluting your local NS with irrelevant bindings. The best idea here is to go back a few steps, decide what exactly it is you need this code to _do_, and find the _clearest_ way to _explicitly_ provide whatever values this local code requires to function correctly. – kungphu Apr 17 '19 at 07:05
  • 1
    Yes I realise that its not a good idea general. But I'm trying to create a function which given an object, returns a string of its imported module (if its a method/attribute of a module), and how it was imported. E.g `In [1]: from numpy import array as ar` `In [2]: from importfuncs import get_import_str` `In [3]: get_import_str(ar)` `Out [1]: 'from numpy import array as ar'` Maybe there is already a function out there? Or a different approach to calling `globals` inside `get_import_str`? – Aldahunter Apr 17 '19 at 19:07
  • 1
    @Aldahunter I have am doing something similar, I just passed globals() as an argument... its not as nice as I want in my API as it requires a user to do this. Still looking for alternatives. – BenedictWilkins Jun 12 '20 at 16:36

1 Answers1

3

Might be a bit controversial, but here you go.

import inspect

def fun(): #some function in another module
    caller_globals = inspect.stack()[1][0].f_globals
    #do what you want 

based on Getting a variable from the caller's globals. What is a frame object?

BenedictWilkins
  • 1,173
  • 8
  • 25