It's my third day using Python, so forgive newbie mistakes. So here's my working code. person.test() registers a callback with the boss, the boss calls the callback, everything works fine.
class Boss:
def registerCallback(self,cb):
self.cb = cb
def doCallback(self):
self.cb()
class Person:
def woot(self,data):
print("Woot! ",data)
def test(self,boss,data):
def callback ():
self.woot(data)
boss.registerCallback(callback)
boss = Boss()
person = Person()
person.test(boss,1)
boss.doCallback()
However, if I change move the callback into an exec(), the closure is lost. The callback runs, but self and data are unknown so the call to self.woot(data) fails.
class Boss:
def registerCallback(self,cb):
self.cb = cb
def doCallback(self):
self.cb()
class Person:
def woot(self,data):
print("Woot! ",data)
def test(self,boss,data):
x = "def callback():\n self.woot(data)\nboss.registerCallback(callback)"
exec(x,globals(),locals())
boss = Boss()
person = Person()
person.test(boss,1)
boss.doCallback()
I tried to compile() too, no luck. Any thoughts? I really don't want to manually carry a copy of self/data through the boss and back, because my real-life code is much more convoluted. I really need a way to maintain the closure.
If you only pass locals
(as the global data for the function), then things more or less work:
class Person:
def woot(self,data):
print("Woot! ",data)
def test(self,boss,data):
x = "def callback():\n self.woot(data)\nboss.registerCallback(callback)"
exec(x, locals())
of course, if you need the globals as well, you can pack them together:
def test(self, boss, data):
namespace = globals().copy()
local_copy = locals().copy()
namespace.update(local_copy)
x = 'def foo(): pass'
exec(x, namespace)