Problem with imported variable

Chris Tavares christophertavares at earthlink.net
Fri Nov 2 12:33:28 CET 2001


"carole valentin" <carole_valentin at yahoo.fr> wrote in message
news:mailman.1004691544.30858.python-list at python.org...
[... snip ...]
>
>
> Here is a very small version of the program:
>
> # ------- File1.py -------
> global var
> var = 2
> print "var1 = ", var  # => var1 = 2
>

This next line is your problem:

> from File2 import *
>
> class Class1:
>     def function1(self):
>         global var
>         var = 3
>         print "var3 = ", var # => var3 = 3
>
>
> first_class = Class1()
> first_class.function1()
> second_class = Class2()
> second_class.function2()
> print "var6 = ", var  # => var6 = 3 , But I would like
> that var6 = 4 !!!
>

from spam import * is the source of much confusion, usually in situations
like this. I'll try and explain what's going on.

When you do a normal import, like "import File2", a module object is
created, and everything that's global in the imported file becomes an
attribute of the module object. In which case, you could refer to your
variable as, for example, File2.var.

from spam import * does something different. It still creates the module
object, but then it goes through the attributes of that module object, and
creates new variables in the current module with the same name, pointing at
the same object.

Now, the thing to remember here is how python variables work. Unlike
languages like C, a variable isn't a chunk of memory - it's a reference to
an object. When you assign, you're not doing a copy, you're changing the
object that reference points to.

So, let's look at file2:

> # ------- File2.py -------
> from File1 import var

This creates a new name (File2.var) which points to the same object as
File1.var.

This is the same as saying:

import File1
var = File1.var

> # if I don't put this line, it says that the variable
> var does not exist

That's because it doesn't.

>
> print "var2 = ", var  # => var2 = 2
>
> class Class2:
>     def function2(self):
>         global var
>         print "var4 = ", var  # => var4 = 2 , But I
> would like that var4 = 3 !!!

It isn't, because the code in File1 did an assignment to it's copy of var.
Since file2's name "var" is separate, it stays pointing to the original
object, in this case the integer object 2.

>         var = 4

Assignment - this will only change File2's "var" - it doesn't affect the one
in File1 at all.

>         print "var5 = ", var  # => var5 = 4
> # -----------------------
>

You should try this instead:

File1.py:

var = 2
print "var = ", var

import File2

class Class1:
    def function1(self):
        global var
        var = 3
        print "var3 = ", var

first_class = Class1()
first_class.function1()
second_class = Class2()
second_class.function2()
print "var6 = ", var

File2.py:

import File1

print "var2 = ", File1.var

class Class2:
    def function2(self):
        print "var4 = ", File1.var
        File1.var = 4
        print "var5 = ", File1.var

Note that I got rid of the from imports, and am explicitly referring to
File1.var in File2. If you run this, you should get what you expect.

I'm probably explaining this very poorly (It's 3:30 am after all), but I
hope I got the idea across. Oh - and "from xxx import * - just say no!"

-Chris






More information about the Python-list mailing list