0

Using Python 2.7. Tried to import a global variable counter from testlib.py, in uselib.py, but return result is 0 in below program in uselib.py, why 2 is not returned? Thanks.

testlib.py,

counter = 0

class Foo:
    def __init__(self):
        pass
    def Count(self):
        global counter
        counter += 1

uselib.py,

from testlib import Foo
from testlib import counter


f = Foo()
f.Count()

g = Foo()
g.Count()

print counter # output is 0 other than 2
Lin Ma
  • 9,739
  • 32
  • 105
  • 175

2 Answers2

1

Per the Python docs:

The import statement combines two operations; it searches for the named module, then it binds the results of that search to a name in the local scope.

So, that implies that the counter you import is just a copy with a label imported into the current scope, meaning modification isn't happening on the right counter.

When you import counter, Python finds the module, takes the counter from testlib, then copies it to uselib. That copy is not modified because you're calls to Count modify the variable in testlib, not the copy you have added to the local scope by importing. This means you print the initial state of counter, but it never is modified, printing 0. To print correctly, use:

print testlib.counter
Andrew Li
  • 55,805
  • 14
  • 125
  • 143
  • Thanks Andrew, does it mean Python import a copy of counter in uselib.py, even before I call Foo.Count? – Lin Ma Sep 19 '16 at 04:42
  • 1
    @LinMa when you write `from testlib import counter`, python searches for `testlib`, and when it finds it, it then finds the `counter` variable. Once it finds it, it copies `counter`'s initial value to `uselib`'s current scope. It's not the counter reference, but the *value*. – Andrew Li Sep 19 '16 at 04:43
  • Thanks Andrew, it copies before I call Foo.Count()? – Lin Ma Sep 19 '16 at 05:13
  • 1
    Yes, it does. `Foo.Count()` modifies the `counter` in testlib, not the imported one – Andrew Li Sep 19 '16 at 05:14
  • 1
    @LinMa If I did help please consider accepting the answer :) – Andrew Li Sep 19 '16 at 05:18
  • Sure Andrew, this is what I just did. :) – Lin Ma Sep 19 '16 at 05:31
1

from testlib import counter introduces a copy of counter. As integer type is immutable, this imported counter would not be affected by operations inside testlib.

You could try something like this instead:

import testlib
print testlib.counter
starrify
  • 14,307
  • 5
  • 33
  • 50