Если вы используете dill
, это позволяет вам обращаться с __main__
так, как если бы это был модуль Python (по большей части). Следовательно, вы можете сериализовать интерактивно определенные классы и т.п. dill
также (по умолчанию) может передавать определение класса как часть рассола.
>>> class MyTest(object):
... def foo(self, x):
... return self.x * x
... x = 4
...
>>> f = MyTest()
>>> import dill
>>>
>>> with open('test.pkl', 'wb') as s:
... dill.dump(f, s)
...
>>>
Затем выключите интерпретатор и отправьте файл test.pkl
по TCP. На вашей удаленной машине теперь вы можете получить экземпляр класса.
Python 2.7.9 (default, Dec 11 2014, 01:21:43)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> with open('test.pkl', 'rb') as s:
... f = dill.load(s)
...
>>> f
<__main__.MyTest object at 0x1069348d0>
>>> f.x
4
>>> f.foo(2)
8
>>>
Но как получить определение класса? Так что это не совсем то, что вы хотели. Однако есть следующее.
>>> class MyTest2(object):
... def bar(self, x):
... return x*x + self.x
... x = 1
...
>>> import dill
>>> with open('test2.pkl', 'wb') as s:
... dill.dump(MyTest2, s)
...
>>>
Затем, после отправки файла… вы можете получить определение класса.
Python 2.7.9 (default, Dec 11 2014, 01:21:43)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> with open('test2.pkl', 'rb') as s:
... MyTest2 = dill.load(s)
...
>>> print dill.source.getsource(MyTest2)
class MyTest2(object):
def bar(self, x):
return x*x + self.x
x = 1
>>> f = MyTest2()
>>> f.x
1
>>> f.bar(4)
17
Поскольку вы искали один вкладыш, я могу сделать лучше. Я не показал, что вы можете отправить класс и экземпляр одновременно, и, возможно, это то, чего вы хотели.
>>> import dill
>>> class Foo(object):
... def bar(self, x):
... return x+self.x
... x = 1
...
>>> b = Foo()
>>> b.x = 5
>>>
>>> with open('blah.pkl', 'wb') as s:
... dill.dump((Foo, b), s)
...
>>>
Тем не менее, это еще не одна строка, но она работает.
Python 2.7.9 (default, Dec 11 2014, 01:21:43)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> with open('blah.pkl', 'rb') as s:
... Foo, b = dill.load(s)
...
>>> b.x
5
>>> Foo.bar(b, 2)
7
Итак, внутри dill
есть dill.source
, и у него есть методы, которые могут обнаруживать зависимости функций и классов и брать их вместе с рассолом (по большей части).
>>> def foo(x):
... return x*x
...
>>> class Bar(object):
... def zap(self, x):
... return foo(x) * self.x
... x = 3
...
>>> print dill.source.importable(Bar.zap, source=True)
def foo(x):
return x*x
def zap(self, x):
return foo(x) * self.x
Так что это не «идеально» (или, возможно, не то, что ожидалось)… но он сериализует код для динамически созданного метода и его зависимостей. Вы просто не получите остальную часть класса, но в этом случае остальная часть класса не нужна. Тем не менее, это не похоже на то, что вы хотели.
Если вы хотите получить все, вы можете просто замариновать всю сессию. И в одной строке (две, считая import
).
>>> import dill
>>> def foo(x):
... return x*x
...
>>> class Blah(object):
... def bar(self, x):
... self.x = (lambda x:foo(x)+self.x)(x)
... x = 2
...
>>> b = Blah()
>>> b.x
2
>>> b.bar(3)
>>> b.x
11
>>> # the one line
>>> dill.dump_session('foo.pkl')
>>>
Затем на удаленной машине...
Python 2.7.9 (default, Dec 11 2014, 01:21:43)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> # the one line
>>> dill.load_session('foo.pkl')
>>> b.x
11
>>> b.bar(2)
>>> b.x
15
>>> foo(3)
9
Наконец, если вы хотите, чтобы транспорт был «выполнен» для вас прозрачно (вместо использования файла), вы можете использовать pathos.pp
или ppft
, которые предоставляют возможность отправлять объекты на второй сервер python (на удаленной машине) или python процесс. Они используют dill
под капотом и просто передают код по проводам.
>>> class More(object):
... def squared(self, x):
... return x*x
...
>>> import pathos
>>>
>>> p = pathos.pp.ParallelPythonPool(servers=('localhost,1234',))
>>>
>>> m = More()
>>> p.map(m.squared, range(5))
[0, 1, 4, 9, 16]
Аргумент servers
является необязательным, и здесь просто подключение к локальной машине через порт 1234
… но если вы вместо этого используете имя и порт удаленной машины (или также), вы перейдете на удаленную машину — «без усилий» .
Получите dill
, pathos
и ppft
здесь: https://github.com/uqfoundation
person
Mike McKerns
schedule
22.01.2015
dict
с json или HDF5 с h5python. Это не отвечает на ваш вопрос, так что это комментарий, но я искренне считаю, что это более жизнеспособное долгосрочное решение. - person Seth Johnson   schedule 17.07.2011