How do I properly update an application handler? In a project I have a very simple application handler that is executed when the current frame change:

import bpy

def frame_handler(scene):
    print("Running frame handler version 1.")

if frame_handler in bpy.app.handlers.frame_change_pre:
    print("Removing handler")
    bpy.app.handlers.frame_change_pre.remove(frame_handler)

print("Adding handler")
bpy.app.handlers.frame_change_pre.append(frame_handler)

print("Number of handlers: " + str(len(bpy.app.handlers.frame_change_pre)))


Adding the handler works fine and it’s executed as expected. But let’s says I want to update my handler to version 2. If I change to the code and run it again I will now have two handlers. When the handler is executed I see that both the old and the new version was running.

In my script I have tried to detect and existing handler and remove it, but clearly that doesn’t work. How do I do that?

My best solution so far is to execute bpy.app.handlers.frame_change_pre.clear() but that feels like cheating :-)

I’m using Blender 2.80 RC3.
Look at the function names and modules

If a function added to handler has a namespace it can be removed quite simply, as shown in the register and unregister methods in and addon.  

def foo():
    print("bar")

def register():
    handers.append(foo)

def unregister():
    handlers.remove(foo)

if __name__ == "__main__":
    register()


The method has that import scope., if however it is added in main thread via a test script then editing to call unregister, rather than register,

if __name__ == "__main__":
    unregister()


foo now compared to then is a totally different foo and will throw an error

Recommend looking at the functions name instead.

EDIT  the module f.__module__ tested against __name__ would be the ideal way to remove these. 

# handlers added to main thread 

my_handlers = [h for h in bpy.app.handlers.frame_change_pre
    if h.__module__ == "__main__"]


The old code uses a test on the functions names.

import bpy

def foo(scene):
    pass

for i in range(4):
    bpy.app.handlers.frame_change_pre.append(foo)

# handlers named "foo"

foo_handlers = [h for h in bpy.app.handlers.frame_change_pre
        if h.__name__ == "foo"]

print(foo_handlers)

for f in foo_handlers:
    bpy.app.handlers.frame_change_pre.remove(f)

foo_handlers = [h for h in bpy.app.handlers.frame_change_pre
        if h.__name__ == "foo"]

print(foo_handlers)


I often use some silly prefix like def ST_____foo(): and remove all handlers with if f.__name__.startswith("ST____")