2

It appears that a class defined in a script has a different scope to one that is imported into the script. For example:

In a file foo.py:

class foo(object):
    def __init__(self):
        print globals()

In my main file:

from foo import foo

class bar(object):
    def __init__(self):
        print globals()

classimport = foo()
classinternal = bar()

The list of globals returned from foo and bar are different - why is this?

It is making life difficult as any class that needs to access the main globals() has to reside in the main file. How do I ensure that the imported class has the same global scope? Some things that I have tried after reading other posts here and here include:

module = __import__("foo", fromlist="foo")
globals()["foo"] = getattr(module, "foo")

and

__builtin__.foo = foo

Any help appreciated!

[EDIT] ---

So per the link above, this is answered in a duplicate article. It turns out that scope is not shared across modules. It mentions several ways around this, but in my case I need to actually create / read / write global variables. So I created a routine in the main script and pass it as an object when foo and bar are initialized. For example:

def PrintGlobals():
    print globals()

class bar(object):
    def __init__(self, PrintGlobals):
        self.PrintGlobals = PrintGlobals
        self.PrintGlobals()

classinternal = bar(PrintGlobals)

(Not my choice of how all this should work, its a hack until I get some time with the application devs :-)

Community
  • 1
  • 1
  • 2
    Instead of using globals, you'd be better off passing required information to functions or methods in a data type. If you use a dictionary for example, that works very well with **kwargs. Or consider using a package like PyYAML to read a configuration file if you need that. What specific problem are you trying to solve? – Michelle Welcks Nov 18 '15 at 21:27
  • Globals belong to the module where the function is defined. – kindall Nov 18 '15 at 21:34
  • 2
    [This post](http://stackoverflow.com/questions/15959534/python-visibility-of-global-variables-in-imported-modules) might give you a nice overview on this issue. – Proghero Nov 18 '15 at 21:39

1 Answers1

2

Here's what the Python 3 FAQ has to say:

In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.

Though a bit surprising at first, a moment’s consideration explains this. On one hand, requiring global for assigned variables provides a bar against unintended side-effects. On the other hand, if global was required for all global references, you’d be using global all the time. You’d have to declare as global every reference to a built-in function or to a component of an imported module. This clutter would defeat the usefulness of the global declaration for identifying side-effects.

To see globals in various scopes, try doing a print(globals()) at various points during your execution. For example: at the top-level module before any code is run, then in __init__.py if you have any code in there (because you import foo), at foo's module level, within each function, and before/after you modify any variables passed to the function.

This answer further explains:

I think the key thing you're missing here is that each module has its own "global" namespace. This can be a bit confusing at first, because in languages like C, there's a single global namespace shared by all external variables and functions. But once you get past that assumption, the Python way makes perfect sense.

Note however that all names assigned in a package __init__.py file are available in the package namespace when you import the package or a module in the package.

Community
  • 1
  • 1
Michelle Welcks
  • 3,513
  • 4
  • 21
  • 34