__main__ and scoping in python

PythonScope

Python Problem Overview


I was somehow surprised by the following behavior:

def main():
    print "%s" % foo

if __name__ == "__main__":
    foo = "bar"
    main()

i.e. a module function has access to enclosing variables in the __main__. What's the explanation for it?

Python Solutions


Solution 1 - Python

Variables in the current modules global scope are visible everywhere in the module -- this rule also holds for the __main__ module.

From Guido's tutorial:

> At any time during execution, there are at least three nested scopes whose namespaces are directly accessible: > > * the innermost scope, which is searched first, contains the local names > * the scopes of any enclosing functions, which are searched starting with the nearest > enclosing scope, contains non-local, but also non-global names > * the next-to-last scope contains the current module’s global names > * the outermost scope (searched last) is the namespace containing built-in names

Solution 2 - Python

The thing here is that:

if __name__ == "__main__":
    foo = "bar"

defines a global variable named foo in that script. so any function of that module will have access to it.

The piece of code listed above is global to the module and not inside any function.

Solution 3 - Python

foo is a module global variable (it's not in any function). All scopes within the module can access it.

Solution 4 - Python

In python there's the global scope, and functions have their own scopes. So it you define foo under the name==main, it's in the global scope. Also, it's not a mistake to use a variable which hasn't been declared yet, in a function, if it will be declared by the time the function will be called.

Solution 5 - Python

As sinelaw pointed out, the way out this annoyance and inadvertent bug/s is to use a function. This function can be within the 'if main:' like this:

if __name__ == "__main__":
    def mainlet():
        foo = "bar"
    mainlet()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDavid CournapeauView Question on Stackoverflow
Solution 1 - PythonSven MarnachView Answer on Stackoverflow
Solution 2 - PythonSantiago AlessandriView Answer on Stackoverflow
Solution 3 - PythonsinelawView Answer on Stackoverflow
Solution 4 - PythonkynnysmattoView Answer on Stackoverflow
Solution 5 - PythongiwyniView Answer on Stackoverflow