global variable confusion

R

rdmurray

Robert D.M. Smith said:
I have a question on global variables and how to use them. I have 2 files;
a.py & b.py

# a.py -----

myvar = { 'test' : '123' }

# -------
# b.py -----

from a import myvar

def test():
a.myvar = { 'blah' : '456' }

# -----

If I *'import a*' & type *'a.myvar'* it prints 'test' & '123'.

Now, if I *'import b'* & type *'b.test()'* ... does this actually change the
contents of myvar? It seems I have to do *'print b.myvar'* to see the change
but really I want to just simply do* 'print myvar'*. I want to be able to
change myvar anywhere. Please help me grasp this concept.

As someone else told you the code above won't work, because you haven't
imported the 'a' that your 'test' function references. But let's
ignore that issue.

I'm guessing the confusion you are experiencing is arising from the
concept of name spaces (a very powerful and ubiquitous concept in Python).
A namespace maps an identifier to a object. A given identifier exists in
exactly one namespace, but many identifiers can refer to the same object.

When you do 'from a import myvar', you are setting the identifier 'myvar'
_in the current model's global namespace_ to point to the same object that
'myvar' does in module a. If, in the current module, you then do, say,
'myvar = 1', what you've done is _rebound_ the identifier 'myvar' in the
current module's global namespace to the integer 1 (an integer object).
You haven't affected anything in module 'a'.

If, on the other hand, you do 'import a', what you've done is bound the
global namespace of module 'a' (an object) to the identifier 'a' in the
current module's global namespace. If you were to do 'a = 1' in the
current module, then you'd rebind the identifier 'a' to the integer 1.
After that a.myvar would be an error.

If, however, you say 'a.myvar = 1', what you've done is rebound the
identifier 'myvar' _in module a's global namespace_ to the integer 1.
Anything that subsequently references a.myvar is going to get '1' as
the result.

Now, to take your brain around the final bend, think about what happens
if one module does 'from a import myvar', and module imported later does
'import a; a.myvar = 1'. The first module bound its global identifier
'myvar' to the object a.myvar originally pointed to (a little dictionary
in your example above). The second module rebinds the identifier myvar in
module a's global namespace to the integer 1. But that doesn't affect
the first module's global namespace. There, the identifier 'myvar'
is still bound _to the original dictionary_.

A modification of your example should make what is going on clearer:

---------------------------
# a.py
myvar = {'test': '123'}
---------------------------
# b.py
from a import myvar
myvar['test'] = '456'
---------------------------

Python 2.6.1 (r261:67515, Jan 7 2009, 17:09:13)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information. {'test': '456'}

The difference between the above and doing 'myvar = 1' is that in the
above code the statement 'myvar['test'] = '456' modifies _the object
that myvar points to_, while 'myvar = 1' modifies _what_ myvar points to.

Study that last sentence until you understand it, and a lot of things
that happen in Python will be much clearer to you (such as what
happens when you pass arguments to a function or method!)

If what I have written doesn't make sense, feel free to ask more
questions.

--RDM
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top