2014-09-22 2 views
1

Я реализую пул процессов с использованием Twisted. Конечной целью является простая функция deferToProcess, очень похожая на deferToThread. Я знаю об модуле ампулы, но я избегаю этого, потому что он, по-видимому, не очень поддерживается, потому что он требует подклассов amp, и потому что я заинтересован в написании этого в любом случае.Отправить метод для подпроцесса

Я хочу, чтобы иметь возможность вызвать любую произвольную статическую функцию в текущем проекте из deferToProcess. Twisted создает любой произвольный процесс, поэтому я получил его для вызова текущего интерпретатора Python с дублированным трактом импорта. Чтобы найти функцию уровня модуля, вы можете просто определить, в каком модуле находится функция, а затем импортировать модуль и вызвать функцию. Мне пришло в голову, что было бы сложно передать ссылку на функцию, например, метод статического класса или лямбда.

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

>>> class Test(object): 
...  @staticmethod 
...  def test(): 
...    print 'Found it!' 
... 
>>> p = multiprocessing.Process(target=Test.test, args=()) 
>>> p.start() 
Found it! 
>>> import sys 
>>> p = multiprocessing.Process(target=lambda: sys.stdout.write('hello\r\n'), args=()) 
>>> p.start() 
hello 
>>> hm='Testing' 
>>> p = multiprocessing.Process(target=lambda: sys.stdout.write(hm), args=()) 
>>> p.start() 
Testing 

Очевидно, что Python должен разветвлять дочерние процессы со всеми этими данными без изменений. Поскольку Twisted фактически порождает свежие процессы, существует ли разумный способ восстановить полный путь для вызова метода, если предположить, что он существует (например, метод не является динамическим)? Это включает в себя функции статического модуля, функции лямбда, назначенные переменной уровня модуля, и статические методы классов. Я не вижу способ сделать это

Например, запустив гипотетическую функцию

findCallPath(Test.test) 

может вернуться

module.module.module.Test.test 

Спасибо заранее.

+0

Кажется, я мог бы сериализовать функции с Dill (https://pypi.python.org/pypi/dill), но мне все еще интересно узнать о моем исходном вопросе. – Salis

+0

Пожалуйста, не используйте заголовок вашего вопроса, чтобы «пометить» его. Я редактировал заголовок. Система тегов - лучший способ убедиться, что люди, интересующиеся вашей темой, видят ваш вопрос. –

+0

«Я знаю модуль ампулы, но я избегаю этого, потому что он, по-видимому, не очень поддерживается» - не повод, чтобы ничего не поддерживать. Так работает open source - право собственности на проект часто меняет руки. –

ответ

1

Функция, которую вы хотите twisted.python.reflect.fullyQualifiedName, который почти делает то, что вы хотите:

>>> from twisted.python.reflect import fullyQualifiedName 
>>> fullyQualifiedName(fullyQualifiedName) 
'twisted.python.reflect.fullyQualifiedName' 

Однако это не дотягивают при взаимодействии со статическими методами:

>>> class Something(object): 
...  @staticmethod 
...  def somethingElse(): 
...   pass 
... 
>>> fullyQualifiedName(Something.somethingElse) 
'__main__.somethingElse' 

Хотя это возможно, ошибка - мы, вероятно, примем патч, который исправит это :).

обратная операция twisted.python.reflect.namedAny (так называемые, потому что есть и другие функции, такие как namedClass и namedModule, но это будет возвращать любой тип вещи):

>>> from twisted.python.reflect import namedAny 
>>> namedAny(fullyQualifiedName(namedAny)) is namedAny 
True 

Надеется, что это помогает!

+1

'twisted.python.reflect.fullyQualifiedName' –