Подтвердить что ты не робот

Истечение нити в python

У меня есть ряд "задач", которые я хотел бы запускать в отдельных потоках. Задачи должны выполняться отдельными модулями. Каждый из них содержит бизнес-логику для обработки своих задач.

Учитывая набор задач, я хотел бы иметь возможность создавать новый поток для каждого модуля следующим образом.

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)

Нет призов для угадывания. Я все еще думаю на С++. Как я могу написать это в Pythonic, используя Pythonic 'enums' и 'switch'es, и иметь возможность запускать модуль в новом потоке.

Очевидно, что все модули будут иметь класс, полученный из ABC (абстрактного базового класса), называемого Plugin. Метод spawnWorker() будет объявлен на интерфейсе плагина и определен в классах, реализованных в различных модулях.

Может быть, есть лучший (т.е. Pythonic) способ сделать все это?. Мне было бы интересно узнать

[изменить]

Я только что читал бота больше, и кажется, что Python не реализует потоки в истинном смысле (по крайней мере, не в том смысле, о котором думал бы программист на С++). В любом случае это не шоу-стоппер для меня. Каждая из задач занимает довольно много времени, и я не хочу задерживать запуск одной задачи до тех пор, пока не будет завершена другая, поэтому я использую потоки. Временная нарезка меня не сильно беспокоит - пока все они начинаются в одно и то же время (или вскоре после друг друга), 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()

Я думаю использовать это для своего плагина ABC. Тогда возникает вопрос, куда я могу поместить код, в котором выполняется фактическая задача (т.е. Бизнес-логика). Я предполагаю, что это идет в методе run() класса Foo (очевидный вопрос, который я знаю, но я не хочу делать какие-либо предположения).

Я думаю о правильном пути или ошибочном (если ошибочно - что я пропустил?)

4b9b3361

Ответ 1

Вместо случая переключения, почему бы не использовать правильный полиморфизм? Например, вот что вы можете сделать с утиным набором в Python:

В, скажем, alice.py:

def do_stuff(data):
    print 'alice does stuff with %s' % data

В, скажем, bob.py:

def do_stuff(data):
    print 'bob does stuff with %s' % data

Затем в вашем клиентском коде, скажем, 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()

Сообщите мне, если мне нужно уточнить.

Ответ 2

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()

Поместите свою логику в функции do_work соответствующих модулей.

Ответ 3

последовательное выполнение

from foobar import alice, bob charles

for fct in (alice, bob charles):
    fct()

параллельное выполнение

from threading import Thread
from foobar import alice, bob charles

for fct in (alice, bob charles):
    Thread(target=fct).start()

Ответ 4

Python может содержать функции как объекты. Чтобы преодолеть ограничение на отсутствие коммутатора, я могу предложить следующее:

case_alice = lambda data : alice.spawnWorker(data)

my_dict[alice] = case_alice

формирование словаря для хранения ваших "случайных" утверждений.

Позвольте мне еще больше сказать:

data = getWorkData()
case_alice = lambda d : alice.spawnWorker( d )
case_bob = lambda d : bob.spawnWorker( d )
case_charles = lambda d : charles.spawnWorker( d )

switch = { alice : case_alice, bob : case_bob, charles : case_charles }
spawn = lambda person : switch[ person ]( data )
[ spawn( item ) for item in (alice, bob, charles )]