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 :-)

3
  • 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? Commented Nov 18, 2015 at 21:27
  • Globals belong to the module where the function is defined. Commented Nov 18, 2015 at 21:34
  • 2
    This post might give you a nice overview on this issue. Commented Nov 18, 2015 at 21:39

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.