question on global variables
James J. Besemer
jb at cascade-sys.com
Thu Oct 10 07:16:40 CEST 2002
mongo57a at comcast.net wrote:
>Somewhat new to Python here.....
>
>I want to change/use a value throughout my program - what I would normally
>refer to as a "global" variable.
>
>I see that there is a "global" command - and I assume its use would be
>global var_name. This I have coded (works) but I am unable to use it "global
>name var_name is not defined".
>
Your interpretation of "global" appears flawed.
You should re-read section 4.1 in the language manual about code blocks
... and namespaces.
The "global" statement declares that variables which otherwise would be
interpreted to be local are actually defined in an outer scope.
The key rule in Python is that names generally are "local" to whatever
scope in which they are assigned a value. This is what you want most of
the time but occasionally leads to some subtle surprises.
# "globals"
count1 = count2 = 0
def func1( n ):
count1 = 0 # creates a new "local" count, distinct from
global one
count2 += n # error: access local count2 before it is defined
...
def func2( n ):
global count1, count2 # causes next two statements to refer
to above globals
count1 = 0
count2 += n
class myobject:
def func3( self, n ):
global count2
count1 = 0 # local
count2 += n # global count2, argument n
self.count1 # a distinct instance variable
In the newer versions of Python, "nested scopes" are implemented. This
means that variables which are NOT assigned-to in a local scope are
looked for in successively outer scopes.
def func3( n ):
global count2 # necessary to make assigned-to local
count2 global
count2 += count1 # otherwise undefined count1 is found in global
scope
Note that local scopes do NOT work in older versions of Python, in which
case you also would have to expressly declare count1 as global in the
above example.
Note that "global" is relative and generally means the outer most scope
of a module. Nevertheless, global names in imported modules generally
are qualified by the module name. E.g.,:
import string
string.join( alist )
Clear as mud?
Once you understand how they work, you should reconsider your need for
globals. In most cases, defining a class with one or more local names
is a better solution.
E.g., instead of:
count = 0
def fn():
global count
...
count += n
you should define a class:
class Counter:
def __init__( self, init=0):
self.count = init
def inc( self, delta=1 ):
self.count += delta
counter = Counter()
def fn():
...
counter.inc( n )
Since the counter name is NOT assigned-to, under nested scope rules you
don't have to declare it global.
In this stilted example, the overhead of the class seems excessive but
in practice, you'll find it to be a vastly superior approach over the
standard "rape and pilage" global style.
Regards
--jb
--
James J. Besemer 503-280-0838 voice
2727 NE Skidmore St. 503-280-0375 fax
Portland, Oregon 97211-6557 mailto:jb at cascade-sys.com
http://cascade-sys.com
More information about the Python-list
mailing list