Python programmers are familiar with the
global
statement , which is how Python lets you assign to global variables inside functions (otherwise any variable that's assigned to is assumed to be a local variable). Well, that's not quite what
global
does.
In languages like C, global variables must exist before you can use them in a function. In common Python usage of
global
, the variable is created at the module (global) level and then assigned to inside a function, in the rough analog of the C requirement:
aglobal = Falsedef enable_thing(): global aglobal aglobal = True
There are good reasons to always create the variables at the module level, but Python does not actually require that you do this. You can actually create a new module level variable inside a function using
global
:
def set_thing(): global a_new_name a_new_name = <something>
(If you read between the lines of the language specification, you can see that this is implied.)
Now, suppose that you want to import a another module as part of initializing some things, but not do it when your module is
import
'ed (for example, you might be dealing with a module that can be very slow to import ). It turns out that you can do this; with
global
you can import something for module-wide use inside a function . The following works:
def import_slowmodule(): global slowmodule import slowmodule def use_slowmodule(): slowmodule.something()
If you do
import
inside a function, it normally binds the imported name only as a function local thing (as
import
defines names in the local scope ). However,
global
changes that; when the module's name (or whatever you're importing it as) is set as a global identifier,
import
binds the name at the module level.
(The actual CPython bytecode does imports in two operations; there is an
IMPORT_NAME
and then some form of
STORE_*
bytecode, normally either
STORE_FAST
or, with a
global
in effect,
STORE_NAME
.)
This is sufficiently tricky and clever that if you need to use it, I think you should put a big comment at the top of the file to explain that there is a module that is conditionally imported at the module level that is not visible in your normal
import
list. Otherwise, sooner or later someone is going to get rather confused (and it may be a future you).