首页 > 解决方案 > Python - 从方法回调到另一个类

问题描述

好家伙!

我阅读了很多关于这个主题的主题,但我无法让它发挥作用。

这是我的示例脚本:

import time, threading, collections


class Factory () :

    def __init__(self):
        self.to_do_list = collections.deque()

    def run(self):
        while self.to_do_list :
            new_task = self.to_do_list.popleft()
            new_task.start(self.done_callback)

    def add_worker(self, task):
        self.to_do_list.append(task)

    def done_callback(self):
            print("OK - DONE")

class Worker (threading.Thread):

    def __init__(self, _name):
        threading.Thread.__init__(self)
        self.name = _name

    def run(self, _callback):
        self.callback = _callback
        for i in range (0,5):
            print(self.name+" -- "+str(i))
            time.sleep(0.5)     
        self.callback()

worker_1 = Worker("Anakin")
worker_2 = Worker("Obi-Wan")
worker_3 = Worker("Yoda")

factory = Factory()

factory.add_worker(worker_1)
factory.add_worker(worker_2)
factory.add_worker(worker_3)

factory.run()

当我运行我的工人时,run(self.done_callback)它运行良好,但我失去了多线程效果。

如果我使用它运行它,start(self.done_callback)我将面临以下错误消息:TypeError: start() takes 1 positional argument but 2 were given

你能向我解释我做错了什么吗?

在此先感谢您的时间 !

标签: pythonmultithreadingclassobject

解决方案


首先,当你运行你的工人new_task.start(self.done_callback)失败时,因为你正在调用threading.Thread.start()它只接收self对象参数。

  • 请注意,当您调用时,new_task.start()您将new_task作为第一个参数隐式传递,相当于:threadhing.Thread.start(new_task)

另外,来自文档

创建线程对象后,必须通过调用线程的 start() 方法来启动其活动。这会在单独的控制线程中调用 run() 方法。

因此,您无法控制 threading.Thread.run() 的调用方式,并且通过添加 _callback 参数来覆盖具有不同签名的此类方法。

这对我来说没有意义,因为您在不提供其实际功能或将其拆分为两个“部分”的情况下进行子类化threading.Thread和覆盖。run()

如果您真的需要这样做,我建议不要将 Thread 子类化并将您的 Worker 替换为以下内容:

class Worker:

def __init__(self, _name):
    self.thread = None
    self.name = _name

def run(self, _callback):
    self.thread = threading.Thread(target=self._p_run, args=(_callback,))
    self.thread.start()

def _p_run(self, _callback):
    for i in range(0, 5):
        print(self.name+" -- "+str(i))
        time.sleep(0.5)
    _callback()

如果需要,您仍然可以访问threading.Thread界面Worker.thread


推荐阅读