I have part of a program written in Python 3.5 and started by testing the first two modules. I managed to isolate a problem in one of the modules where it appears that two global variables are switching back to their original values for no reason that I can understand. One of these global variables (event_count
) is used in only a single function (grep shows the string "event_count" doesn't appear anywhere else in any of my *.py files), yet the value of the variable changes between calls to the function. If I add print statements for the other global variable in this module, it also reverts to it's original value at the same moment. Moving event_count
to another module (replacing it with sensorlogic.event_count
in eventcount()
and moving the initialization to the other module) makes the behavior go away, so I have a fix but no understanding.
Here is all of the code that uses event_count
, in module sensoreval
:
event_count = 0
def eventcount(increment):
global event_count
print("entering eventcount, increment =", increment,
", event_count =", event_count)
event_count += increment
print("leaving eventcount, event_count =", event_count)
return event_count
If I run the following code segment:
e.setvalue(1)
print("I am at marker #1")
eventcount(0)
(the last action in e.setvalue()
is a call to eventcount(0)
) it produces this output:
entering eventcount, increment = 0 , event_count = 4
leaving eventcount, event_count = 4
I am at marker #1
entering eventcount, increment = 0 , event_count = 0
leaving eventcount, event_count = 0
I have tried trimming down the two modules to something of reasonable size, but the problem keeps going away when I do so. I'll keep working on that. Since I've never used Python 3 before, and only have a little Python 2.7 experience I assume I'm doing something stupid, I just have no idea what.
I believe that my example is different from some of the related posts that have been pointed out in that the variable event_count
is global only so it will be static. It is used only in this single function. The string "event_count" doesn't appear anywhere else in this or any other module.
After many edit/rerun iterations, I have a managably small example that demonstrates what is happening. It involves two modules with a total of 8 lines of code. The first module, a.py
, is __main__
:
import b
c = 0
if __name__ == '__main__':
b.init()
print("c =", c)
The second module is b.py
:
import a
def init():
a.c = 1
Running a.py
produces the output:
c = 0
I expected c
to still be 1 from the a.c = 1
in b.py
.
Also, I tried to reduce this further by deleting the if __name__ == '__main__'
from a.py
, but then the example no longer runs:
Traceback (most recent call last):
File "...\a.py", line 1, in <module>
import b
File "...\b.py", line 1, in <module>
import a
File "...\a.py", line 3, in <module>
b.init()
AttributeError: module 'b' has no attribute 'init'
I can't explain that, either, but it seems likely to be related.
Following Mata's lead, I believe that the following code shows what's going on. There are three modules involved. a.py
:
print("__name__ =", __name__)
import b
print("__name__ =", __name__)
def f(): pass
print(f)
if __name__ == '__main__':
print("f is b.a.f?", f is b.a.f)
b.py
:
import a
c.py
:
import a
import b
print("__name__ =", __name__)
print("a.f is b.a.f?", a.f is b.a.f)
You can see the problem by running a.py
, giving the result:
__name__ = __main__
__name__ = a
__name__ = a
<function f at 0x0000021A4A947840>
__name__ = __main__
<function f at 0x0000021A484E0400>
f is b.a.f? False
Running c.py
so that __main__
isn't part of the import cycle results in:
__name__ = a
__name__ = a
<function f at 0x000001EA101B7840>
__name__ = __main__
a.f is b.a.f? True