Search code examples
pythontimer

How to pass arguments to the threading.Timer callback?


I tried this code:

import threading

def hello(arg, kargs):
    print(arg)

t = threading.Timer(2, hello, "bb")
t.start()

while 1:
    pass

The output is just b instead of bb.

How can I pass arguments to the callback properly?

If I remove the kargs parameter from hello, I get an exception that says TypeError: hello() takes 1 positional argument but 2 were given. Why? Where did the kargs value come from in the first code?


Solution

  • Timer expects a sequence (normally, a list or tuple) of arguments and a mapping (normally, a dict) of keyword arguments, so pass a list instead:

    import threading
    
    def hello(arg):
        print(arg)
    
    t = threading.Timer(2, hello, ["bb"])
    t.start()
    
    while 1:
        pass
    

    Since "bb" is an iterable, the Timer will iterate over it and use each element as a separate argument; threading.Timer(2, hello, "bb") is equivalent to threading.Timer(2, hello, ["b", "b"]).

    Use a dictionary to pass any keyword arguments to the callback, for example:

    def hello(arg, kwarg):
        print('arg is', arg, 'and kwarg is', kwarg)
    
    t = threading.Timer(2, hello, ["bb"], {'kwarg': 1})