Photon
Photon

Reputation: 3222

Python global variables and callbacks

I'm writing a program that involves callbacks called from another module, and which need to access a global variable.
It seems that changes assigned to the global variable are not seen in the callback function, which only sees the original assignment. I'm guessing due to the import from the other module.
What is the proper way to write this pattern?

First module:

# a.py
from b import runb

myGlobal=None

def init():
    global myGlobal
    myGlobal=1

def callback():
    print myGlobal

def main():
    init()
    runb()

if __name__=='__main__':
    main()

Second module:

#b.py
def runb():
    from a import callback
    callback()

I would expect this program to print '1', but instead it prints 'None'

EDIT: init can only be called once (it is a simplification of a complex program)

Upvotes: 3

Views: 4520

Answers (4)

Michael Hutter
Michael Hutter

Reputation: 1542

a.py

from b import *

def MyCallback(sText):
  global MyGlobalVar
  print("You can call this function from both modules: ", end="")
  print(sText + ", GlobalVar=" + str(MyGlobalVar))

RegisterMyCallback(MyCallback)

MyGlobalVar = 1
MyCallback("Called from a.py")

MyGlobalVar = 2
DoSomethingInModuleB()

b.py

def RegisterMyCallback(MyCallbackFunction):
    global MyCallback
    MyCallback = MyCallbackFunction

def DoSomethingInModuleB():
    MyCallback("Called from b.py")


Output:

$ python3 a.py
You can call this function from both modules: Called from a.py, GlobalVar=1
You can call this function from both modules: Called from b.py, GlobalVar=2

Upvotes: 0

Janne Karila
Janne Karila

Reputation: 25207

Python imports the main module as __main__. When b.py imports a by its actual name, a new instance of the module is loaded under the name a. Each instance has its own myGlobal.

One solution is this:

#b.py
def runb():
    from __main__ import callback
    callback()

Another solution is to create a new main module. Import a there and make an explicit call to a.main().

Upvotes: 5

Rajesh Kumar
Rajesh Kumar

Reputation: 1290

If you do this, "from a import callback", then again "myGlobal=None" will be executed, making it to print "None"

Upvotes: 2

jasal
jasal

Reputation: 1053

The main() function is not called when you import the file as a module. __name__ == "main" is true only when a.py is executed directly.

Upvotes: 1

Related Questions