0

I usually don't think too hard about variable scope in python, but I wanted to see if there's a clean explanation for this. Given two files called main.py and utils.py:

utils.py

def run():
 print(L)

main.py

import utils
def run():
 print(L)
if __name__ == '__main__':
 L = [1,2]
 run() 
 utils.run() 

The first run() call in main.py runs fine despite L not being fed into run(), and the utils.run() call raises a NameError. Is L a global variable available to all functions defined in main.py?

If I imported utils with from utils import * instead of import utils, would that change anything?

asked Feb 11, 2021 at 17:22

2 Answers 2

1

It's module-level scope. A global variable defined in a module is available to all functions defined in the same module (if it's not overriden). Functions in another module don't have access to another module's variables unless they import them.

About "If I imported utils with from utils import * instead of import utils, would that change anything?": No. The scope is determined at parsing time.

Check this for more information.

Notably:

It is important to realize that scopes are determined textually: the global scope of a function defined in a module is that module’s namespace, no matter from where or by what alias the function is called. On the other hand, the actual search for names is done dynamically, at run time [...]

So the global scopes of both functions for variables defined in a module are the modules they're defined in. For one, its module also later has a definition for a global variable it uses, but not the other module, and when it's time to check for a variable when a function is run, each checks their own module's variables definitions, one finds it, the other does not.

answered Feb 11, 2021 at 17:34
Sign up to request clarification or add additional context in comments.

Comments

1

See Python's FAQ. Their implementation of scope is a compromise between convenience and the dangers of globals.

Variables are treated as globals if they're only referenced by a function, and need to be explicitly declared as globals (e.g. global foo ) inside of the function body if you want to edit them. If you edit run() to try and change the value of L, you'll get an error.

What's happening here is that your Python code imports utils, and then runs run(). This function sees that you're looking for a variable named "L," and checks your global namespace.

answered Feb 11, 2021 at 17:30

2 Comments

You should clarify that the if __name__ == '__main__': block is not inside a function. Usually people define a function like def main() and then just put a call to main() in their __main__ block. So anything you declare in it is obviously global. If you call utils.run() before defining L then you'll get an error, but if you do it after then L will be defined so there will be no error.
Both of these answers were good. I didn't realize that putting variables in the __name__ == '__main__' block defines them as globals to the module. I now clearly understand the need for putting a main() function call inside the __main__ block. Thanks!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.