Параллельный Python: передача функции, написанной в другом модуле, для «отправки»

Я использую модуль Parallel Python (pp) и хочу отправить задание работнику. Однако функция, которую я хочу выполнить, находится в другом модуле (написанном с помощью Cython), и я не знаю, как импортировать имя функции в новый рабочий процесс. Метод, предложенный здесь, т.е. импорт модуля "walkerc" внутри функции не может работать, так как сама прогулка определена в walkerc из имени файла "walkerc.so"

import pp
from walkerc import walk
# Other stuff here
ser = pp.Server()
# Some more definitions
ser.submit(walk, (it, params))
ser.submit(walk, (1000, params), modules = ("walkerc",), globals = globals())

Оба приведенных выше утверждения терпят неудачу, я получаю следующую ошибку:

Traceback (последний последний вызов):

Файл "", строка 1, в ser.submit(walk, (1000, params), modules = ("walkerc",), globals = globals())

Файл "/usr/lib/python2.7/site-packages/pp.py", строка 458, в поле submit sfunc = self.__dumpsfunc((func, ) + depfuncs, modules)

Файл "/usr/lib/python2.7/site-packages/pp.py", строка 629, в __dumpsfunc sources = [self.__get_source(func) for func in funcs]

Файл "/usr/lib/python2.7/site-packages/pp.py", строка 696, в __get_source sourcelines = inspect.getsourcelines(func)[0]

Файл "/usr/lib/python2.7/inspect.py", строка 690, в строках getsourcelines, lnum = findsource(object)

Файл "/usr/lib/python2.7/inspect.py", строка 526, в файле findsource = getfile(object)

Файл «/usr/lib/python2.7/inspect.py», строка 420, в getfile «функция, трассировка, фрейм или объект кода». формат (объект))

TypeError: '‹' встроенная функция walk'>' не является модулем, классом, методом, функцией, трассировкой, фреймом или объектом кода.

Сама функция «прогулка» правильно импортируется в основную программу, проблематичным является процесс отправки ее новому работнику.

Как я могу правильно указать имя функции «прогулка»? Я не хочу определять «прогулку» в том же файле, в котором я его назвал, потому что я изменил его в Cython и хочу иметь лучшую производительность. Есть ли альтернатива?


person Abhinav    schedule 24.06.2014    source источник


Ответы (1)


Попробуйте переименовать свою функцию walk во что-нибудь другое, например mywalk. Как следует из текста исключения, ваша среда имеет встроенную функцию с именем walk, поэтому inspect путается.

Я могу успешно передать мою импортированную функцию walk, как это, в моей системе, здесь нет конфликта и ничего больше не нужно, функция выполняется с использованием данного аргумента:

import pp
from walkerc import walk

pps = pp.Server()
pps.submit(walk, args=(1,))

Но передача dir, которая наверняка является встроенной функцией:

pps.submit(dir)

Я получаю ту же ошибку, что и вы:

Traceback (most recent call last):
  File "parallel.py", line 9, in 
    pps.submit(dir)
  ...
  File ".../lib/python2.7/inspect.py", line 420, in getfile
    'function, traceback, frame, or code object'.format(object))
TypeError:  is not a module, class, method, function, traceback, frame, or code object

Обновление после обсуждения ниже:

Таким образом, проблема здесь в том, что Python обрабатывает члены, полученные из расширений C, как созданные. -ins. Приведенный выше код работает с обычным модулем Python, но мне удалось воспроизвести ошибку OP при импорте и передаче функции из расширения C.

Поэтому я завернул вызов функции расширения C в обычную функцию Python, что делает свое дело. Обратите внимание, что теперь импорт функции walk был перемещен в функцию-оболочку, чтобы она могла сама создавать свой собственный контекст при отправке.

import pp

def walk(n):
    import walkerc
    return walkerc.walk(n)

def print_callback(result):
    print('callback: ', result)

pps = pp.Server()
job = pps.submit(walk, args=(1,), callback=print_callback)
person famousgarkin    schedule 24.06.2014
comment
Спасибо за предложение. Однако это странно, потому что когда я открываю интерпретатор и импортирую функцию mywalk, она отображается как <built-in function mywalk>. Я думаю, это потому, что я импортирую его из скомпилированного файла .so. Если я импортирую его из модуля .py, он будет импортирован как <function walk at 0x7f883a4ca7d0> - person Abhinav; 24.06.2014
comment
Я предполагаю, что настоящий вопрос заключается в том, как импортировать модуль Cython, чтобы он был практически таким же, как импорт модуля .py. Спасибо за указатель, я приму этот ответ, если решу проблему. :) - person Abhinav; 24.06.2014
comment
@Abhinav Вы правы, я пропустил, что вы импортируете из .so. Мне просто удалось воспроизвести проблему. Если я импортирую из .so, я также получаю ошибку «встроенная функция». Я изучаю это дальше сейчас :) - person famousgarkin; 24.06.2014
comment
Только что увидел, что если вы делаете import inspect, а затем inspect.isfunction(walkerc.mywalk), он показывает False для модуля .so, но True для модуля .py. В документации в isfunction сказано, что если объект является определяемой пользователем функцией, он возвращает True. И для этого нужны атрибуты func_code, которых нет в модуле .so, предположительно потому, что он не скомпилирован? Значит ли это, что нет никакого способа сделать это? - person Abhinav; 24.06.2014
comment
@Abhinav Да, глядя на то же самое. Изначально было непонятно, но согласно документам по расширениям и некоторым другим ссылкам на это похоже, что расширения считаются встроенными в целом, и именно так Python их обрабатывает, включая модуль inspect. Я пытаюсь обернуть вызов функции расширения в обычную функцию Python, но пока безуспешно. - person famousgarkin; 24.06.2014
comment
@Abhinav Я обновил вопрос тем, что обнаружил. Кажется, есть решение, я просто немного боролся с C :) - person famousgarkin; 24.06.2014