如何给 threading.Timer 的回调传递参数?

42 投票
2 回答
56298 浏览
提问于 2025-04-16 08:23

我试了这段代码:

import threading

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

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

while 1:
    pass

输出结果只是 b,而不是 bb

我该怎么正确地把参数传给回调函数呢?

如果我把 hello 函数里的 kargs 参数去掉,就会出现一个错误,提示 TypeError: hello() takes 1 positional argument but 2 were given。这是为什么呢?那在第一段代码里,kargs 的值又是从哪里来的呢?

2 个回答

5

Timer的第三个参数中,你需要传入一个序列。如果你传入"bb"这个序列,意思是hello会把这个序列中的元素(也就是两个"b")当作不同的参数来处理,分别对应argkargs。如果把"bb"放在一个列表里,hello就会把这个字符串当作第一个参数来接收:

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

可以推测,hello应该是设计成接受这样的参数:

def hello(*args, **kwargs):

想了解这个语法的详细解释,可以查看双星号(**)和星号(*)在参数中的作用是什么?

84

Timer 这个东西需要你给它一串参数(通常是列表或元组)和一组关键字参数(通常是字典),所以你应该传一个列表进去:

import threading

def hello(arg):
    print(arg)

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

while 1:
    pass

因为 "bb" 是一个可迭代的对象,Timer 会逐个遍历它,把每个元素当作单独的参数来用;所以 threading.Timer(2, hello, "bb")threading.Timer(2, hello, ["b", "b"]) 是一样的。

如果你想给回调函数传递一些关键字参数,可以用字典来传,比如:

def hello(arg, kwarg):
    print('arg is', arg, 'and kwarg is', kwarg)

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

撰写回答