Is there a way to set an objects id or memory position? Ultimately I'm trying to change function "a" to function "b" while still preserving any saved reference to function "a"

I think you may be over-thinking. This works as expected:

def fun_a():
  return "I am function a"

def fun_b():
  return "I'm b"

s = { 'a': fun_a, 'b': fun_b}
print("s['a'](): %s"%s['a']())
print("s['b'](): %s"%s['b']())

keep_fun = fun_a
fun_a = fun_b

print("After fun_a = fun_b")
print("s['a'](): %s"%s['a']())
print("s['b'](): %s"%s['b']())
print("call fun_a() direct: %s"%fun_a())
print("call fun_b() direct: %s"%fun_b())
print("call keep_fun() direct: %s"%keep_fun())

Here's the thing.
function starts as:
<function fun_a at 0x027C4330>

after it is set to fun_b it becomes:
<function fun_b at 0x0053D3F0>

I'm trying to find a way to set it to function b while keeping it indistinguishable from its former self... I'm trying to change a function after wxpython binds to that function. Currently, if I change the function wx still calls an old saved copy of the original.... Can you see any way around this?

I think you are out of luck doing it directly because wxPython is keeping the reference. Can you do it with a function wrapper? For instance, just off the top of my head:

class Dispatcher:
  def __init__(self, aFunction):
     self.function = aFunction
  def __call__(*args):
     return self.function(*args)

# Now you can do something like this
wrapper_a = Dispatcher(func_a)
# and you can call wrapper_a(*args) here
wrapper_a.function = func_b
# and now it calls func_b, but its location in memory did not change

Does this work?

What does your code look like where you bind it?

If it now looks like wx_[I]something[/I](my_callback) just replace it with wx_[I]something[/I](Dispatcher([I]my_callback[/I])) Later, when you ask wxpython for your callback, it gives you the Dispatcher object, into which you may replace the underlying callback function as needed.

Or maybe you keep your own collection of callback functions, in which case, you make it a collection of Dispatcher(callback)

Either way, it looks to me as if the effort is limited and may happen all in one place in your code if you structured it that way. Of course, you will have the place(s) where you alter the dispatched function, but that is new code anyway.

here's my final code. Had to make a couple of adjustments:

class Dispatcher:
   """ An intermediary between binded events and there routines.
   Allows altering of functions without destroying the initial references """
   def __init__(self, aFunction):
      import __main__
      self.name = aFunction.__name__
      if hasattr(aFunction, 'im_self'):
         self.container = aFunction.im_self
      else:
         self.container = __main__
         

   def __call__(self, *args):
      function = getattr(self.container, self.name)
      return function(*args)
This question has already been answered. Start a new discussion instead.