我有一系列'任务',我想在不同的线程中运行.任务将由单独的模块执行.每个都包含用于处理其任务的业务逻辑.
给定一个任务元组,我希望能够为每个模块生成一个新线程,如下所示.
from foobar import alice, bob charles
data = getWorkData()
# these are enums (which I just found Python doesn't support natively) :(
tasks = (alice, bob, charles)
for task in tasks
# Ok, just found out Python doesn't have a switch - @#$%!
# yet another thing I'll need help with then ...
switch
case alice:
#spawn thread here - how ?
alice.spawnWorker(data)
Run Code Online (Sandbox Code Playgroud)
没有猜测的奖品我还在用C++思考.如何使用Pythonic'enums'和'switch'以Pythonic方式编写它,并能够在新线程中运行模块.
显然,这些模块都有一个派生自一个名为Plugin的ABC(抽象基类)的类.spawnWorker()方法将在Plugin接口上声明,并在各种模块中实现的类中定义.
也许,有一种更好的(即Pythonic)做这一切的方式?我有兴趣知道
[编辑]
我刚刚读了一个机器人,似乎Python没有真正意义上的线程实现(至少,不是C++程序员会想到的意义).在任何情况下,这对我来说都不是一个限制.每个任务都相当耗时,我不想阻止启动一个任务直到另一个任务完成,这就是我使用线程的原因.时间切片并不会让我感到烦恼 - 只要它们几乎同时启动(或者不久之后),Python就可以在它们之间尽可能多地进行时间间隔 - 这对我很好.
我在SO上看到了类似问题的答案.
用户提供了一个简单的线程类,如下所示:
import threading
class Foo (threading.Thread):
def __init__(self,x):
self.__x = x
threading.Thread.__init__(self)
def run (self):
print str(self.__x)
for x in xrange(20):
Foo(x).start()
Run Code Online (Sandbox Code Playgroud)
我正在考虑将此用于我的ABC插件.那么我的问题是我将代码放在实际任务完成的位置(即业务逻辑).我假设这是在Foo类的run()方法中(我知道明显的问题,但我不想做任何假设).
我的想法是在正确的轨道上还是有缺陷的(如果有缺陷 - 我错过了什么?)
San*_*nta 37
而不是switch-case,为什么不使用适当的多态?例如,在这里您可以使用Python中的duck typing进行操作:
在比方说alice.py:
def do_stuff(data):
print 'alice does stuff with %s' % data
Run Code Online (Sandbox Code Playgroud)
在比方说bob.py:
def do_stuff(data):
print 'bob does stuff with %s' % data
Run Code Online (Sandbox Code Playgroud)
然后在您的客户端代码中,例如main.py:
import threading
import alice, bob
def get_work_data():
return 'data'
def main():
tasks = [alice.do_stuff, bob.do_stuff]
data = get_work_data()
for task in tasks:
t = threading.Thread(target=task, args=(data,))
t.start()
Run Code Online (Sandbox Code Playgroud)
如果我需要澄清,请告诉我.
import threading
from foobar import alice, bob, charles
data = get_work_data() # names_in_pep8 are more Pythonic than camelCased
for mod in [alice, bob, charles]:
# mod is an object that represent a module
worker = getattr(mod, 'do_work')
# worker now is a reference to the function like alice.do_work
t = threading.Thread(target=worker, args=[data])
# uncomment following line if you don't want to block the program
# until thread finishes on termination
#t.daemon = True
t.start()
Run Code Online (Sandbox Code Playgroud)
将您的逻辑放在do_work相应模块的功能中.