Mailing List Archive

How do can you make a variable static?
Hello:
I hope somebody can help me with this problem (python newbie, <<week)

I have a dictionary called SymHanDict. It's entries are comprised of a
"symbol handle" number (the key), and a numeric value. A function foo()
resides in another module. When called, it's supposed to look at
SymHanDict, and create a new entry comprised of an incremented handle
number (the highest handle number in the existing dictionary plus one),
and a default data value of 0.

I keep getting name errors on SymHanDict, even though I've specified it
as global. I've seen the FAQ and thumbed through a borrowed copy of
Programming Python (M. Lutz). I don't see anything that allows me to
declare variables as static, and I don't understand the explanation of
globals in python.

Can anyone clarify? What's the workaround? For a variety of reasons I
won't go into right now, I really can't pass the dictionary as an
argument.

Thanks

Pete


**** the following contained in main module test.py
*****************************
from foo import foo

SymHanDict={0:0}

foo() #each call to foo() should add items to
the dictionary
foo()
foo()

*** the following contained in module foo.py ************************
def foo():
global SymHanDict

handlelist=SymHanDict.keys() # get the list of existing
handles
handlelist.sort() # sort the list, then

handle=handlelist[len(handlelist)-1] # find largest handle
handle=handle+1 # generate new handle, and
SymHanDict[handle]=0 # add it to dictionary along
with
# a default value of zero.

print SymHanDict




--

-----------------------------------------------
| The opinions expressed here are my own, |
| and not necessarily those of my employer. |
-----------------------------------------------
How do can you make a variable static? [ In reply to ]
> from foo import foo
>
> SymHanDict={0:0}
>
> foo() #each call to foo() should add items to
> the dictionary
> foo()
> foo()
>
> *** the following contained in module foo.py ************************
> def foo():
> global SymHanDict

Global means look for it in the foo.py module

In this case SymHanDict is in another file and your best bet is to pass it
to foo(). If you just don't want to do that try something like this in the
module where you plan to call foo().

import foo

SymHanDict={0:0}

def myFoo():
foo.foo(SymHanDict)


Passing a parm is much cleaner than globals anyway.
Might I suggest using a class:

class Foo:
def __init__(self, dict):
self._myDict=dict

def __call__(self):
"""Do foo stuff here"""
pass

myFoo = Foo(SymHanDict)

# Call the foo thing here.
myFoo()


--Darrell
How do can you make a variable static? [ In reply to ]
In article <3772AE33.AA764DFA@alliedsignal.com>,
H. P. Friedrichs <HPeter.Friedrichs@alliedsignal.com> wrote:
>
>Can anyone clarify? What's the workaround? For a variety of reasons I
>won't go into right now, I really can't pass the dictionary as an
>argument.

Just as a reminder, "pass the dictionary" actually means "pass a
*reference* to the dictionary"; if copying a huge block of memory is an
issue, that's simply not happening.

If you really want to do exactly what you're doing (and Darrell's
suggestion of using a class is far better), you could create something
like this (not tested, but I'm pretty sure it works):

*** module foo.py

def initFoo ( dict ) :
global SymHanDict
SymHanDict = dict

Now your Foo() function should work correctly if you call initFoo()
first in the main script.
--
--- Aahz (@netcom.com)

Hugs and backrubs -- I break Rule 6 <*> http://www.rahul.net/aahz/
Androgynous poly kinky vanilla queer het
How do can you make a variable static? [ In reply to ]
The reason you're getting a NameError is that
the name SymHandDict is in a different module
from the one where you're referring to it.
The "global" statement you put in doesn't make
any difference to that.

For what you're doing here, you don't need or
want a "global" statement at all. You only need
one if you want to assign to a module-level variable
from within a function defined in the same module.
You're not doing that here. You're changing the
contents of the object to which SymHandDict refers,
but you're not assigning to the variable SymHandDict
itself -- it still refers to the same object afterwards.

In general, the way you refer to a name in a *different*
module is by prefixing it with the name of the module
(which you must also import using an "import" statement),
e.g. in module foo:

import test

def foo():
handlelist=test.SymHanDict.keys()
...
test.SymHanDict[handle]=0

***BUT*** I wouldn't recommend you do it exactly that
way in this case, because then your two modules would
be importing from each other, a situation which can
lead to difficulties and is best avoided if possible.

If there will only ever be one instance of SymHanDict,
I'd suggest moving it either into module foo or some
other module which foo imports.

If you put it in module foo, you will be able to refer
to it directly without any prefix:

# in module foo:

SymHanDict = {0:0}

def foo():
handlelist = SymHanDict.keys()
...
SymHanDict[handle] = 0

If module test needs to decide how to initialise
SymHanDict, it can do this:

# in module test:
import foo
foo.SymHanDict = {0:0}

> I don't understand the explanation of
> globals in python.

Keep in mind that there are only two namespaces you
can reference without using any prefix: (1) the
"local" scope (parameters and local variables of the
current function) and (2) the so-called "global"
scope, which is not completely global, but is
only the top level of the current module (i.e.
the one containing the piece of code being
executed).

To refer to anything in another module, you have
to use the module.name syntax.

Finally, the "global" statement is only needed in
one special circumstance, which is quite rare:
when you want to assign to a name in the current
module from within a function, without prefixing it
with a module name. For example,

x = 42

def blarg():
global x
x = 17

blarg()
print x

prints 17. If the "global" statement weren't there,
the assignment would assign to a *local* variable
called x, and the global x would be unchanged.

However, note that you *don't* need a global
statement to do this:

x = 42

def blarg():
print x

nor do you need one to do this:

import banana

def blarg():
banana.x = 17

blarg()
print banana.x

Hope I've helped more than I've confused,
Greg






>
> Can anyone clarify? What's the workaround? For a variety of reasons I
> won't go into right now, I really can't pass the dictionary as an
> argument.
>
> Thanks
>
> Pete
>
> **** the following contained in main module test.py
> *****************************
> from foo import foo
>
> SymHanDict={0:0}
>
> foo() #each call to foo() should add items to
> the dictionary
> foo()
> foo()
>
> *** the following contained in module foo.py ************************
> def foo():
> global SymHanDict
>
> handlelist=SymHanDict.keys() # get the list of existing
> handles
> handlelist.sort() # sort the list, then
>
> handle=handlelist[len(handlelist)-1] # find largest handle
> handle=handle+1 # generate new handle, and
> SymHanDict[handle]=0 # add it to dictionary along
> with
> # a default value of zero.
>
> print SymHanDict
>
> --
>
> -----------------------------------------------
> | The opinions expressed here are my own, |
> | and not necessarily those of my employer. |
> -----------------------------------------------