В качестве продолжения этого вопроса: Есть ли простой способ замариновать функцию Python (или иным образом сериализовать ее код)?
Я хотел бы увидеть пример этой пули из сообщения выше:
«Если функция ссылается на глобальные переменные (включая импортированные модули, другие функции и т. д.), которые вам нужно подобрать, вам нужно будет сериализовать эти тоже или воссоздать их на удаленной стороне. В моем примере просто указано глобальное пространство имен удаленного процесса».
У меня есть простой тест, в котором я пишу байтовый код функции в файл, используя marshal:
def g(self,blah):
print blah
def f(self):
for i in range(1,5):
print 'some function f'
g('some string used by g')
data = marshal.dumps(f.func_code)
file = open('/tmp/f2.txt', 'w')
file.write(data)
Затем запускаю новый экземпляр Python, который я делаю:
file = open('/tmp/f2.txt', 'r')
code = marshal.loads(file.read())
func2 = types.FunctionType(code, globals(), "some_func_name");
func2('blah')
В результате получается:
NameError: global name 'g' is not defined
Это не зависит от различные подходы, которые я сделал для включения g. Я пробовал в основном тот же подход к отправке g как f, но f все еще не может видеть g. Как поместить g в глобальное пространство имен, чтобы его мог использовать f в процессе получения?
Кто-то также порекомендовал взглянуть на пиротехнику как на пример того, как это сделать. Я уже пытался понять соответствующий код в проекте disco. Я взял их класс dPickle и безуспешно попытался воссоздать их функциональность disco/tests/test_pickle.py в отдельном приложении. В моем эксперименте были проблемы с маршалингом функций с вызовом дампов. В любом случае, возможно, следующим будет пироразведка.
Подводя итог, можно сказать, что основная функциональность, которую я ищу, — это возможность отправить метод по сети и получить вместе с ним все основные методы «рабочей области» (например, g).
Пример с изменениями из ответа:
Работающая функция_сочинитель:
import marshal, types
def g(blah):
print blah
def f():
for i in range(1,5):
print 'some function f'
g('blah string used by g')
f_data = marshal.dumps(f.func_code)
g_data = marshal.dumps(g.func_code);
f_file = open('/tmp/f.txt', 'w')
f_file.write(f_data)
g_file = open('/tmp/g.txt', 'w')
g_file.write(g_data)
Работающая функция_считыватель:
import marshal, types
f_file = open('/tmp/f.txt', 'r')
g_file = open('/tmp/g.txt', 'r')
f_code = marshal.loads(f_file.read())
g_code = marshal.loads(g_file.read())
f = types.FunctionType(f_code, globals(), 'f');
g = types.FunctionType(g_code, globals(), 'g');
f()