Вы можете лучше управлять глобальными объектами, импортировав __main__
и используя методы, доступные в этом модуле. Это то, что dill делает для сериализации почти всего в python. По сути, когда укроп сериализует интерактивно определенную функцию, он использует некоторое искажение имени на __main__
как на стороне сериализации, так и на стороне десериализации, что делает __main__
допустимым модулем.
>>> import dill
>>>
>>> def bar(x):
... return foo(x) + x
...
>>> def foo(x):
... return x**2
...
>>> bar(3)
12
>>>
>>> _bar = dill.loads(dill.dumps(bar))
>>> _bar(3)
12
На самом деле, укроп регистрирует свои типы в реестре pickle
, поэтому, если у вас есть какой-то код черного ящика, который использует pickle
, и вы не можете его редактировать, то простой импорт укропа может волшебным образом заставить его работать без обезьяньих исправлений стороннего кода.
Или, если вы хотите, чтобы весь сеанс интерпретатора был отправлен как «изображение Python», укроп также может это сделать.
>>> # continuing from above
>>> dill.dump_session('foobar.pkl')
>>>
>>> ^D
dude@sakurai>$ python
Python 2.7.5 (default, Sep 30 2013, 20:15:49)
[GCC 4.2.1 (Apple Inc. build 5566)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> dill.load_session('foobar.pkl')
>>> _bar(3)
12
Вы можете легко отправить образ через ssh на другой компьютер и начать там, где вы остановились, если есть совместимость версий pickle и обычные предостережения об изменении python и устанавливаемых вещах.
На самом деле я использую укроп для сериализации объектов и отправки их по параллельным ресурсам с помощью параллельного Python, многопроцессорности и mpi4py. Я удобно сворачиваю их в пакет pathos (и pyina для MPI), который обеспечивает единый map
интерфейс для различных серверных частей параллельной пакетной обработки.
>>> # continued from above
>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> Pool(4).map(foo, range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
>>> from pyina.launchers import MpiPool
>>> MpiPool(4).map(foo, range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Существуют также неблокирующие и итерационные карты, а также непараллельные соединения труб. У меня тоже есть пафосный модуль для pp
, однако он несколько нестабилен для функций, определенных в __main__
. Я работаю над улучшением этого. Если хотите, разветвите код на github и помогите улучшить pp
для функций, определенных в __main__
. Причина, по которой pp
плохо обрабатывается, заключается в том, что pp
выполняет свои трюки с сериализацией, используя временные файловые объекты и читая историю сеанса интерпретатора... поэтому он не сериализует объекты так же, как многопроцессорность или mpi4py. У меня есть модуль укропа dill.source
, который без проблем выполняет тот же тип травления, что и pp
, но он довольно новый.
person
Mike McKerns
schedule
17.10.2013