我正在尝试使用 python 2.7 线程模块并行调用 2 个函数,并且为了让自己更轻松,我编写了自己的AsycTask
类。
class AsyncTask:
def __init__(self, task, name="async-task", callback=None):
self.task = task
self.t = None
if self.task is not None:
if callback is not None:
self.t = threading.Thread(target=lambda: [task(), callback()], name=name)
else:
self.t = threading.Thread(target=self.task, name=name)
def start(self):
if self.t is not None:
self.t.start()
else:
Log.warn("Can't start async task: thread is None")
def join(self):
if self.t is not None:
self.t.join()
else:
Log.warn("Can't join async task: thread is None")
但是当我传递函数句柄时,我得到了一些奇怪的结果。
在其他地方我有这门课:
class Foo:
def __init__(self, id):
self.id = id
def bar(self, args):
result = None
# do some stuff that takes a while
time.sleep(10)
Log.debug("bar() called in object %s" % self.id)
return result
然后我创建一个 foo 的列表
foos = []
foos.append(Foo("1"))
foos.append(Foo("2"))
并bar
异步调用
results = []
tasks = []
for foo in foos:
args = "some stuff"
fn = foo.bar
Log.debug("before async: " + str(foo))
task = AsyncTask(lambda: [Log.debug("in async: " + str(fn)), results.append(fn(args))])
tasks.append(task)
task.start()
for task in tasks:
task.join()
# process results
当我运行它时,我得到:
before async: <__main__.Foo instance at 0x7f9caef7e200>
before async: <__main__.Foo instance at 0x7f9caef7e248>
in async: <bound method Foo.bar of <__main__.Foo instance at 0x7f9caef7e248>>
in async: <bound method Foo.bar of <__main__.Foo instance at 0x7f9caef7e248>>
bar() called in object 2
bar() called in object 2
请注意,bar()
在第一个Foo
实例上永远不会调用它,而在第二个实例上它会被调用两次。
我没有大量的 python 经验,所以很明显,我做错了什么,不能正确理解线程和函数句柄在 python 中的工作方式。
什么是更 Pythonic 的方式来实现这一点?