2016-09-07 8 views
2

Мне нужно передать список объектов функции, которая выполняется в потоке в python. Мне нужно иметь возможность вызывать функции этих объектов, например animal.bite(). Я создал обобщенный класс тест:Как передать список объектов функции потока

class test_class:  
    def f(self): 
     print 'hello' 

и создал список этих объектов:

test_object = test_class() 
new_object = test_class() 
strlist = [test_object, new_object] 

и есть функция, которая создает поток, если один не был уже создан:

def threadScheduler(*stringlist): 
    global lock #variable defined elsewhere, makeshift resource lock 
    if not lock: 
     print "creating thread" 
     lock = True 
     thread = threading.Thread(name='heartbeat', target=threadWorkLoad, args=(stringlist,)) 
     thread.start() 

Это функция threadWorkLoad:

def threadWorkLoad(*stringlist): 
    global lock 
    for item in stringlist: 
     print 'in thread', item.f() 
    time.sleep(2) 
    lock = False 
    return 

и это главный цикл:

for x in range(0,10): 
    print 'in main thread', strlist[0].f() 
    threadScheduler(strlist) 
    time.sleep(1) 

То, что я хотел бы сделать это, чтобы иметь возможность вызвать функцию f() на объекты в списке в threadWorkLoad, но в настоящее время я получаю ошибку AttributeError: 'tuple' object has no attribute 'f'

Если я заменю эти объекты на строки, код работает так, как я хочу. Но мне нужно иметь возможность делать то же самое с объектами. Как это сделать в python?

EDIT:

Некоторые другие вещи, которые я попробовал -

Я изменившие создание нити в threadScheduler к thread = threading.Thread(name='heartbeat', target=threadWorkLoad, args=[stringlist]) не повезло.

Я также попытался поставить в следующем заявлении в качестве первой линии threadScheduler:

print 'in scheduler', stringlist[0].f()

, и я получаю ту же ошибку. Похоже, проблема связана с передачей объектов списка в качестве параметра функции.

Я также должен уточнить, что мы используем Python 2.5.2.

+0

Является ли запятая после строкового списка в 'thread = threading.Thread (name = 'heartbeat', target = threadWorkLoad, args = (stringlist,))' намеренный? Я ожидаю, что это будет связано с вашей проблемой. –

+0

@ScottMermelstein Да, я столкнулся с этим в другом вопросе. Хотя я также попытался заменить 'args = (stringlist,)' на 'args = [stringlist]', и я получаю точно такую ​​же ошибку. На самом деле, я пробовал что-то еще (я изменю свой OP, чтобы показать вам, что), и это тоже не сработало, поэтому я совершенно уверен, что это не причина проблемы. – Lighthat

+1

Еще одна вещь, которую нужно попробовать: вместо 'args = (stringlist,)' или 'args = [stringlist]', попробуйте 'args = tuple (stringlist)'. Проблема заключается в том, как вы настраиваете аргументы. Он ожидает кортеж аргументов, в то время как вы пытаетесь передать ему 1-кортеж со списком в качестве единственного члена этого кортежа. –

ответ

1

Два изменения должны были быть сделаны для этой работы (благодаря Scott Mermelstein):

В главном цикле, threadScheduler(strlist) должен был быть изменен на threadScheduler(*strlist). Я проверил это, добавив следующую строку в функции threadScheduler():

print 'in scheduler', stringlist[0].f() 

и смог успешно назвать f() только после того, как я добавил звездочку. Я не уверен, почему аргумент должен был пройти таким образом.

Кроме того, я должен был изменить

thread = threading.Thread(name='heartbeat', target=threadWorkLoad, args=(stringlist,)) 

в

thread = threading.Thread(name='heartbeat', target=threadWorkLoad, args=tuple(stringlist)) 

Тогда я был в состоянии успешно назвать f() для каждого объекта в списке в функции threadWorkLoad().