I'm currently learning Python, and I have to work on a Python 2.7 project.
Accessing "module scope" variables in functions of the module itself is a bit confusing for me, and I didn't succeed in finding a satisfying way.
My attempts so far:
Way 1:
my_module.py
my_global_var = None
def my_func():
global my_global_var
my_global_var = 'something_else'
Here I think that confusing local and "module scope" vars may be quite easy.
Way 2:
my_module.py
import my_module
my_global_var = None
def my_func():
my_module.my_global_var = 'something_else'
Here, the name of "my_module" could not be as easily changed as "way 1" when necessary. Plus, importing a module into itself sounds quite weird.
What would you recommend? Or would you suggest something else? Thanks.
Importing a module within itself can have unwanted side effects (like evaluating statements more than once.) I would suggest using "Way 1" and a tool like pylint to help verify your code and enforce common practices.
PyLint can be found at: http://www.logilab.org/project/pylint
Way 1 is the correct way when you absolutely must rebind a global variable. However you should ask yourself why you are modifying a global and whether there is something better you can do (such as encapsulating the behaviour in a class).
Importing a module into itself should be avoided as it is error prone. If the module is also a script you would sometimes need to import
__main__
instead, or if the module is part of a package maybe you should be importingfoo.my_module
. In short, don't do that.Avoid setting globals at all. You can create new namespaces with classes quite easily, so use class variables if you must.
For anything serious you need a proper design with classes anyways.
You probably want to read up on Python's namespaces. Way 1 is correct but generally unnecessary, never use 2. An easier approach is to just use a dict (or class or some other object):
Assignments always go into the innermost scope and the innermost scope is always searched first, thus the need for the global keyword. In this case you aren't assigning to a name, so it's unnecessary.