Global Local Tutorial

Abstract

Usually, in Python, scope is handled naturally and can be easily ignored. Occasionally, it can create hard to debug problems. This tutorial will help with those cases.

Prerequisite

global_vs_local_variables

Script Controller

Run this script multiple times in the same game using a Script Controller.

from random import randrange
 
globalNum = randrange(100)
 
print('global in global:', globalNum)
print('------')
 
def localFunc():
    localNum = randrange(100)
    print('global in local:', globalNum)
    print('local in local:', localNum)
    print('--------')

Each time this script is run it prints 'global in global' with a different number. It doesn't run localFunc at all. Basically the script is being created and destroyed each time it is run. Now change the code to this.

from random import randrange
 
globalNum = randrange(100)
 
print('global in global:', globalNum)
print('------')
 
def localFunc():
    localNum = randrange(100)
    print('global in local:', globalNum)
    print('local in local:', localNum)
    print('--------')
 
localFunc()
localFunc()
print('----End Script----')

Notice that 'global in global' is only printed once per run, but 'global in local' and 'local in local' is printed twice. Also notice that globalNum is derived once per run, while localNum is rederived twice. Each time the script is run, golbalNum is rederived.

Module Controller

Run localFunc multiple times in the same game using a Module Controller.

from random import randrange
 
globalNum = randrange(100)
 
print('global in global:', globalNum)
print('------')
 
def localFunc():
    localNum = randrange(100)
    print('global in local:', globalNum)
    print('local in local:', localNum)
    print('--------')

We can see that 'global in global' is printed once, 'global in local' always prints the same, and 'local in local' is printed differently. Its important to understand that globalNum = randrang(100) will only be run once, no matter how many times the module is run. In some cases this is desirable, sometimes not. Take the following code.

import bge
cont = bge.logic.getCurrentController()
own = cont.owner
 
def ownPrt():
    print(own)

No matter who runs this module, own will always equal the first object that ran it! That is obviously not what we want. Instead we could do this.

import bge
 
def ownPrt():
    cont = bge.logic.getCurrentController()
    own = cont.owner    
    print(own)

Now own is rederived each time. Sometimes it's preferable to run code only once. For instance.

import util
 
class Inventory():
    def __init__():
        gold = 0
        iron = 0
 
util.inventory = Inventory()
 
def goldAdd():
    util.inventory.gold += 1
 
def ironAdd():
    util.inventory.iron += 1

No matter how many times goldAdd or ironAdd is run by a module controller, util.inventory will only be created once. Also once it is created, we can retrieve it from anywhere just by importing util. Nice!

Further Reading

Scope
Aliasing
Side Effects

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License