Gav*_*Roy 37 python multithreading
鉴于Python文档为Thread.run():
您可以在子类中覆盖此方法.标准的run()方法调用传递给对象构造函数的可调用对象作为目标参数(如果有),分别使用args和kwargs参数中的顺序和关键字参数.
我构造了以下代码:
class DestinationThread(threading.Thread):
def run(self, name, config):
print 'In thread'
thread = DestinationThread(args = (destination_name, destination_config))
thread.start()
Run Code Online (Sandbox Code Playgroud)
但是当我执行它时,我收到以下错误:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 522, in __bootstrap_inner
self.run()
TypeError: run() takes exactly 3 arguments (1 given)
Run Code Online (Sandbox Code Playgroud)
我似乎错过了一些明显的东西,但我看到的各种例子都与这种方法有关.最终我试图将字符串和字典传递给线程,如果构造函数不是正确的方法,而是在启动线程之前创建一个新函数来设置值,我对此持开放态度.
有关如何最好地完成此任务的任何建议?
Jer*_*rub 68
你真的不需要继承Thread.API支持这一点的唯一原因是让来自Java的人们感觉更舒服,这是唯一能够做到这一点的方法.
我们建议您使用的模式是将方法传递给Thread构造函数,然后调用.start().
def myfunc(arg1, arg2):
print 'In thread'
print 'args are', arg1, arg2
thread = Thread(target=myfunc, args=(destination_name, destination_config))
thread.start()
Run Code Online (Sandbox Code Playgroud)
这是使用线程传递参数而不是扩展的示例__init__:
import threading
class Example(threading.Thread):
def run(self):
print '%s from %s' % (self._Thread__kwargs['example'],
self.name)
example = Example(kwargs={'example': 'Hello World'})
example.start()
example.join()
Run Code Online (Sandbox Code Playgroud)
以下是使用多重处理的示例:
import multiprocessing
class Example(multiprocessing.Process):
def run(self):
print '%s from %s' % (self._kwargs['example'],
self.name)
example = Example(kwargs={'example': 'Hello World'})
example.start()
example.join()
Run Code Online (Sandbox Code Playgroud)
文档threading.Thread似乎暗示任何未使用的位置和关键字args都会被传递给run.他们不是.
任何额外的位置args和关键字kwargs确实被默认threading.Thread.__init__方法捕获,但它们只传递给使用target=关键字指定的方法.它们不会传递给run()方法.
实际上,Threading文档清楚地表明它是使用被捕获的args run()调用提供的target=方法的默认方法,并且kwargs:
"你可以在子类中重写这个方法.标准的run()方法调用传递给对象构造函数的可调用对象作为目标参数,如果有的话,分别从args和kwargs参数中获取顺序和关键字参数."
如果您想保留面向对象的方法并且还具有运行参数,您可以执行以下操作:
import threading
class Destination:
def run(self, name, config):
print 'In thread'
destination = Destination()
thread = threading.Thread(target=destination.run,
args=(destination_name, destination_config))
thread.start()
Run Code Online (Sandbox Code Playgroud)
如上所述,也可以通过以下方式完成partial
from functools import partial
import threading
class Destination:
def run(self, name, config):
print 'In thread'
destination = Destination()
thread = threading.Thread(target=partial(
destination.run, destination_name, destination_config))
thread.start()
Run Code Online (Sandbox Code Playgroud)
与纯函数方法相比,这样做的优点是它可以让您保持其他现有的面向对象代码相同。唯一的变化是让它不是 Thread 的子类,这应该不是什么大问题,因为根据threading.Thread文档:
只重写该类的init ()和run()方法
如果您要重写 Thread 以便可以从子类中访问线程对象,那么我建议您仅在对象中使用 threading.currentThread() 。这样,您就可以根据 Tim Peters 的“Python 之禅”将线程的命名空间与您自己的命名空间分开:
命名空间是一个非常棒的想法——让我们多做一些这样的事情吧!