2017-01-21 9 views
1

я хочу сделать следующее:сериализации/мариновать функцию, которая определена в строке

import pickle 
namespace = {} 
exec('def f(x): return x', namespace) 
pickle.dumps(namespace['f']) 

Однако это приводит к следующей ошибке:

--------------------------------------------------------------------------- 
PicklingError        Traceback (most recent call last) 
<ipython-input-102-61493bb3c732> in <module>() 
     2 namespace = {} 
     3 exec('def f(x): return x', namespace) 
----> 4 pickle.dumps(namespace['f']) 

PicklingError: Can't pickle <function f at 0x7f2134171950>: it's not the same object as __main__.f 

Проблема, что я хочу Решите: у меня есть функция в строчном формате, и мне нужно иметь возможность ее сериализовать (для целей распараллеливания).

+0

Вы должны объяснить, что в настоящее время происходит в вашем коде, который не отвечает ожиданиям. Что происходит, когда этот код работает прямо сейчас. Что вы ожидаете, должно случиться. Что * точно * вы пытаетесь достичь с помощью своего кода? Пожалуйста, пересмотреть, как собрать более твердый [mcve], чтобы лучше понять ваш вопрос. – idjaw

+0

Спасибо за ваш комментарий, я добавил сообщение об ошибке. Более того, я думаю, что я достаточно четко описываю свою проблему. – johnbaltis

ответ

1

Я не уверен, почему использование используемого тега dill в вашем вопросе, потому что вы использовали только pickle ... но если вам действительно нужен ваш код, чтобы точно так вы его написали, с одной оговоркой, которую вы можете заменить pickle с dill ... это работает:

>>> import dill as pickle 
>>> namespace = {} 
>>> exec('def f(x): return x', namespace) 
>>> _f = pickle.dumps(namespace['f']) 
>>> _f 
'\x80\x02cdill.dill\n_create_function\nq\x00(cdill.dill\n_load_type\nq\x01U\x08CodeTypeq\x02\x85q\x03Rq\x04(K\x01K\x01K\x01KCU\x04|\x00\x00Sq\x05N\x85q\x06)U\x01xq\x07\x85q\x08U\x08<string>q\tU\x01fq\nK\x01U\x00q\x0b))tq\x0cRq\r}q\x0e(U\x0c__builtins__q\x0fc__builtin__\n__dict__\nh\nh\x00(h\rh\x0eh\nNN}q\x10tq\x11Rq\x12uh\nNNh\x10tq\x13R0h\x12.' 
>>> f = pickle.loads(_f) 
>>> f(5) 
5 
>>> 
1

Вы можете просто передать текущее пространство имен global в exec, затем вы можете разложить f соборование:

import pickle 
exec('def f(x): return x', globals()) 
pickle.dumps(f) 

ли вы можете загрузить его в другой среде, это совершенно другой вопрос, как это обсуждалось here.

1

без использования globals() следующих работ, а также:

import pickle 
namespace = {} 
exec('def f(x): return x', namespace) 
f = namespace['f'] # has to have the same name 
pickle.dumps(f) 

Функция берется из namespace должен быть определен в пространстве имен функции под тем же названием.

 Смежные вопросы

  • Нет связанных вопросов^_^