我尝试了这段代码:
import threading
def hello(arg, kargs):
print(arg)
t = threading.Timer(2, hello, "bb")
t.start()
while 1:
pass
输出只是
b
而不是 bb
。
如何正确地将参数传递给回调?
如果我从
kargs
中删除 hello
参数,我会得到一个异常,显示 TypeError: hello() takes 1 positional argument but 2 were given
。为什么?第一个代码中的 kargs
值来自哪里?
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})
Timer
的第三个参数是一个序列。将 "bb"
作为该序列传递意味着 hello
获取该序列的元素("b"
和 "b"
)作为单独的参数(arg
和 kargs
)。将 "bb"
放入列表中,hello
将获取字符串作为第一个参数:
t = threading.Timer(2, hello, ["bb"])
大概,
hello
的目的是具有如下参数:
def hello(*args, **kwargs):
有关此语法的详细说明,请参阅 **(双星/星号)和 *(星号/星号)对参数有何作用?。