Python's global
statement and imports in functions
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).
Comments on this page:
|
|