Other Ways to Access Globals

Interestingly, because global-scope variables morph into the attributes of a loaded module object, we can emulate the global statement by importing the enclosing module and assigning to its attributes, as in the following example module file. Code in this file imports the enclosing module, first by name, and then by indexing the sys.modules loaded modules table (more on this table in Chapter 21):

# thismod.py

var = 99                              # Global variable == module attribute

def local():
    var = 0                           # Change local var

def glob1():
    global var                        # Declare global (normal)
    var += 1                          # Change global var

def glob2():
    var = 0                           # Change local var
    import thismod                    # Import myself
    thismod.var += 1                  # Change global var

def glob3():
    var = 0                           # Change local var
    import sys                        # Import system table
    glob = sys.modules['thismod']     # Get module object (or use __name__)
    glob.var += 1                     # Change global var

def test():
    print(var)
    local(); glob1(); glob2(); glob3()
    print(var)

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

When run, this adds 3 to the global variable (only the first function does not impact it):

>>> import thismod
>>> thismod.test()
99
102
>>> thismod.var
102

This works, and it illustrates the equivalence of globals to module attributes, but it’s much more work than using the global statement to make your intentions explicit.

As we’ve seen, global allows us to change names in a module outside a function. It has a cousin named nonlocal that can be used to change names in enclosing functions, too, but to understand how that can be useful, we first need to explore enclosing functions in general.

 


[38] Multithreading runs function calls in parallel with the rest of the program and is supported by Python’s standard library modules _thread, threading, and queue (thread, threading, and Queue in Python 2.6). Because all threaded functions run in the same process, global scopes often serve as shared memory between them. Threading is commonly used for long-running tasks in GUIs, to implement nonblocking operations in general and to leverage CPU capacity. It is also beyond this book’s scope; see the Python library manual, as well as the follow-up texts listed in the Preface (such as O’Reilly’s Programming Python), for more details.