Global variables in a Python module spontaneously reset
<p>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 (<code>event_count</code>) 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 <code>event_count</code> to another module (replacing it with <code>sensorlogic.event_count</code> in <code>eventcount()</code> and moving the initialization to the other module) makes the behavior go away, so I have a fix but no understanding.</p>

<p>Here is all of the code that uses <code>event_count</code>, in module <code>sensoreval</code>:</p>

<pre><code>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
</code></pre>

<p>If I run the following code segment:</p>

<pre><code>    e.setvalue(1)
    print("I am at marker #1")
    eventcount(0)
</code></pre>

<p>(the last action in <code>e.setvalue()</code> is a call to <code>eventcount(0)</code>) it produces this output:</p>

<pre><code>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
</code></pre>

<p>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.</p>

<p>I believe that my example is different from some of the related posts that have been pointed out in that the variable <code>event_count</code> 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.</p>

<hr>

<p>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, <code>a.py</code>, is <code>__main__</code>:</p>

<pre><code>import b
c = 0
if __name__ == '__main__': 
    b.init()
    print("c =", c)
</code></pre>

<p>The second module is <code>b.py</code>:</p>

<pre><code>import a
def init():
    a.c = 1
</code></pre>

<p>Running <code>a.py</code> produces the output:</p>

<pre><code>c = 0
</code></pre>

<p>I expected <code>c</code> to still be 1 from the <code>a.c = 1</code> in <code>b.py</code>.</p>

<p>Also, I tried to reduce this further by deleting the <code>if __name__ == '__main__'</code> from <code>a.py</code>, but then the example no longer runs:</p>

<pre><code>Traceback (most recent call last):
  File "...\a.py", line 1, in &lt;module&gt;
    import b
  File "...\b.py", line 1, in &lt;module&gt;
    import a
  File "...\a.py", line 3, in &lt;module&gt;
    b.init()
AttributeError: module 'b' has no attribute 'init'
</code></pre>

<p>I can't explain that, either, but it seems likely to be related.</p>

<hr>

<p>Following Mata's lead, I believe that the following code shows what's going on. There are three modules involved. <code>a.py</code>:</p>

<pre><code>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)
</code></pre>

<p><code>b.py</code>:</p>

<pre><code>import a
</code></pre>

<p><code>c.py</code>:</p>

<pre><code>import a
import b
print("__name__ =", __name__)
print("a.f is b.a.f?", a.f is b.a.f)
</code></pre>

<p>You can see the problem by running <code>a.py</code>, giving the result:</p>

<pre><code>__name__ = __main__
__name__ = a
__name__ = a
&lt;function f at 0x0000021A4A947840&gt;
__name__ = __main__
&lt;function f at 0x0000021A484E0400&gt;
f is b.a.f? False
</code></pre>

<p>Running <code>c.py</code> so that <code>__main__</code> isn't part of the import cycle results in:</p>

<pre><code>__name__ = a
__name__ = a
&lt;function f at 0x000001EA101B7840&gt;
__name__ = __main__
a.f is b.a.f? True
</code></pre>