2
$\begingroup$

I am trying to use a timer for a function, but I need to provide it a parameter so I'm using the example from https://docs.blender.org/api/blender2.8/bpy.app.timers.html:

import bpy
import functools

def print_message(message):
    print("Message:", message)

bpy.app.timers.register(functools.partial(print_message, "Hello"), first_interval=2.0)

The problem is that I don't know how to unregister it. Trying with this:

if bpy.app.timers.is_registered(functools.partial(print_message, "World"):
    bpy.app.timers.unregister(functools.partial(print_message, "World")

Or this:

if bpy.app.timers.is_registered(print_message):
    bpy.app.timers.unregister(print_message)

Or even this:

   if bpy.app.timers.is_registered(functools):
        bpy.app.timers.unregister(functools)

And a lot of other things, but that doesn't work. Any idea? Thanks!

$\endgroup$
  • 1
    $\begingroup$ bpy.app.timers has not unregister function, but timer function can return False to stop execution, try look at this $\endgroup$ – RUben Jun 2 '19 at 14:26
  • $\begingroup$ I have been able to unregister timers, it actually unregisters if I don't check if it's registered first (it does throw an error though, maybe it's trying to unregister itself twice). But the return None solution works great, so thanks for your help! $\endgroup$ – chafouin Jun 2 '19 at 14:34
  • 1
    $\begingroup$ @RUben bpy.app.timers has an unregister function listed here $\endgroup$ – Ray Mairlot Jun 2 '19 at 15:11
  • $\begingroup$ It's a bit weird that bpy.app.timers.is_registered doesn't work when using parameters. It must be expecting a specific argument that I don't know about. $\endgroup$ – chafouin Jun 3 '19 at 15:20
1
$\begingroup$

I am not an expert in Python, but if my knowledge from JavaScript translates well enough, then this is caused by the fact that the created function references are not equal. Let's say, you have a function called a:

def a(x, y):
    return x + y

It is stored as a reference, that can be assigned to multiple variables that will be equal to each other and itself as well:

print(a == a) # True
b = a
print(a == b) # True

But each time you call functools.partial, it creates a new function reference, which are then not equal to each other, not even if their parameters are the same:

c = functools.partial(a, 5)
d = functools.partial(a, 5)
print(c == d) # False

Or alternatively you can even directly compare the results.

print(functools.partial(a, 5) == functools.partial(a, 5)) # False

Because of this, if you want to later unregister a function created with functools.partial, you need to store a reference to it, so Python will be able to find which one to unregister by checking for equality among the registered ones, like for example this way:

e = functools.partial(print_message, "World")
bpy.app.timers.register(e, first_interval=2.0)

after which you can use the following code to unregister:

if bpy.app.timers.is_registered(e):
    bpy.app.timers.unregister(e)

because

print(e == e) # True
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.