Ответ 1
Я автор dill
. Я делаю эту вещь более ssh
, но с успехом. В настоящее время dill
и любой другой сериализатор распиливают модули по ссылке... поэтому для успешного прохождения функции, определенной в файле, вы должны убедиться, что соответствующий модуль также установлен на другой машине. Я не верю, что есть какой-либо сериализатор объектов, который напрямую сериализует модули (т.е. Не по ссылке).
Сказав, что dill
имеет некоторые опции для сериализации зависимостей объектов. Например, для экземпляров класса значением по умолчанию в dill
является не сериализация экземпляров класса по ссылке... поэтому определение класса также может быть сериализовано и отправлено с экземпляром. В dill
вы также можете (использовать очень новую функцию) сериализовать дескрипторы файлов, сериализируя файл, вместо того, чтобы делать это по ссылке. Но опять же, если у вас есть случай функции, определенной в модуле, вам не повезло, так как модули сериализованы по ссылке довольно чертовски универсально.
Возможно, вы сможете использовать dill
для этого, просто не с травлением объекта, а с извлечением источника и отправкой исходного кода. В pathos.pp
и pyina
, dill
нас использовали для извлечения исходных и зависимостей любого объекта (включая функции) и передачи их на другой компьютер/процесс/и т.д.. Однако, поскольку это нелегко, dill
также может использовать переход на другой ресурс при попытке извлечь соответствующий импорт и отправить его вместо исходного кода.
Вы можете понять, надеюсь, это грязная грязная вещь (как указано в одной из зависимостей функции, которую я извлекаю ниже). Однако то, что вы запрашиваете, успешно выполняется в пакете pathos
для передачи кода и зависимостей на разные машины через ssh-туннелированные порты.
>>> import dill
>>>
>>> print dill.source.importable(dill.source.importable)
from dill.source import importable
>>> print dill.source.importable(dill.source.importable, source=True)
def _closuredsource(func, alias=''):
"""get source code for closured objects; return a dict of 'name'
and 'code blocks'"""
#FIXME: this entire function is a messy messy HACK
# - pollutes global namespace
# - fails if name of freevars are reused
# - can unnecessarily duplicate function code
from dill.detect import freevars
free_vars = freevars(func)
func_vars = {}
# split into 'funcs' and 'non-funcs'
for name,obj in list(free_vars.items()):
if not isfunction(obj):
# get source for 'non-funcs'
free_vars[name] = getsource(obj, force=True, alias=name)
continue
# get source for 'funcs'
#…snip… …snip… …snip… …snip… …snip…
# get source code of objects referred to by obj in global scope
from dill.detect import globalvars
obj = globalvars(obj) #XXX: don't worry about alias?
obj = list(getsource(_obj,name,force=True) for (name,_obj) in obj.items())
obj = '\n'.join(obj) if obj else ''
# combine all referred-to source (global then enclosing)
if not obj: return src
if not src: return obj
return obj + src
except:
if tried_import: raise
tried_source = True
source = not source
# should never get here
return
Я предполагаю, что что-то может быть также построено вокруг метода dill.detect.parents
, который предоставляет список указателей на все родительские объекты для любого заданного объекта... и можно было бы восстановить все зависимости функций как объекты... но это не реализовано.
BTW: для создания туннеля ssh просто выполните следующее:
>>> t = pathos.Tunnel.Tunnel()
>>> t.connect('login.university.edu')
39322
>>> t
Tunnel('-q -N -L39322:login.university.edu:45075 login.university.edu')
Затем вы можете работать через локальный порт с помощью ZMQ
или ssh
или что угодно. Если вы хотите сделать это с помощью ssh
, pathos
также имеет встроенную функцию.