2017-01-21 11 views
1

문자열에 정의 된 함수를 피클 : 직렬화/I는 다음을 수행 할

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

pickle 만 사용했기 때문에 dill 태그를 사용하는 이유는 확실하지 않지만 대체 할 수있는 한 가지주의 사항이있는 코드를 작성한 방법이 정말 필요한 경우 pickledill와 함께 ... 그것은 작동 :

>>> 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 같은 완전히 다른 문제이다. 뿐만 아니라 globals() 다음 작품을 사용하지 않고

1

:

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

namespace에서 촬영 기능은 동일한 이름으로 함수 네임 스페이스에 정의해야합니다.