Передача cPickled данных в метод компиляции (py2 vs py3) - PullRequest
0 голосов
/ 13 апреля 2020

Ниже приведена очень упрощенная версия моей проблемы, возникающей в моей системе. Я передаю маринованную команду на C ++, затем получаю ее обратно в Python и создаю из нее объект кода. Он отлично работает в Python 2, но в Python 3 я делаю следующее и не работаю, как ожидалось.

Может кто-нибудь сказать правильный способ сделать это?

Python 2:

In [45]: def test(pickle): 
    ...:     return cPickle.loads(pickle) 

In [46]: s = cPickle.dumps(('.'.join(('test',)), (numpy.array([1007261]), True, True), {}), protocol=0)

In [48]: cmd_str = 'test("""%s""")' % (s)

In [49]: cmd_str
Out[49]: 'test("""(S\'test\'\np1\n(cnumpy.core.multiarray\n_reconstruct\np2\n(cnumpy\nndarray\np3\n(I0\ntS\'b\'\ntRp4\n(I1\n(I1\ntcnumpy\ndtype\np5\n(S\'i8\'\nI0\nI1\ntRp6\n(I3\nS\'<\'\nNNNI-1\nI-1\nI0\ntbI00\nS\'\\x9d^\\x0f\\x00\\x00\\x00\\x00\\x00\'\ntbI01\nI01\nt(dt.""")'

In [50]: eval(compile(cmd_str, 'test', 'eval'))
Out[50]: ('test', (array([1007261]), True, True), {})

Python 3:

In [166]: s = cPickle.dumps(('.'.join(('test',)), (numpy.array([1007261]), True, True), {}), protocol=0)                                               

In [167]: s                                                                                                                                                     
Out[167]: b'(Vtest\np0\n(cnumpy.core.multiarray\n_reconstruct\np1\n(cnumpy\nndarray\np2\n(I0\ntp3\nc_codecs\nencode\np4\n(Vb\np5\nVlatin1\np6\ntp7\nRp8\ntp9\nRp10\n(I1\n(I1\ntp11\ncnumpy\ndtype\np12\n(Vi8\np13\nI0\nI1\ntp14\nRp15\n(I3\nV<\np16\nNNNI-1\nI-1\nI0\ntp17\nbI00\ng4\n(V\x9d^\x0f\\u0000\\u0000\\u0000\\u0000\\u0000\np18\ng6\ntp19\nRp20\ntp21\nbI01\nI01\ntp22\n(dp23\ntp24\n.'

In [168]: cmd_Str = 'test(b"""(Vtest\np0\n(cnumpy.core.multiarray\n_reconstruct\np1\n(cnumpy\nndarray\np2\n(I0\ntp3\nc_codecs\nencode\np4\n(Vb\np5\nVlatin1\np6\
     ...: ntp7\nRp8\ntp9\nRp10\n(I1\n(I1\ntp11\ncnumpy\ndtype\np12\n(Vi8\np13\nI0\nI1\ntp14\nRp15\n(I3\nV<\np16\nNNNI-1\nI-1\nI0\ntp17\nbI00\ng4\n(V\x9d^\x0f\\u
     ...: 0000\\u0000\\u0000\\u0000\\u0000\np18\ng6\ntp19\nRp20\ntp21\nbI01\nI01\ntp22\n(dp23\ntp24\n.""")'                                                     

In [169]: eval(compile(cmd_Str, 'test', 'eval'))                                                                                                                
Traceback (most recent call last):

  File "/usr/local/python/python-3.7/std/lib64/python3.7/site-packages/IPython/core/interactiveshell.py", line 3375, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)

  File "<ipython-input-169-1325204980ec>", line 1, in <module>
    eval(compile(cmd_Str, 'test', 'eval'))

  File "test", line 54
SyntaxError: bytes can only contain ASCII literal characters.

Я также заметил, что это работает в Python 2, так как на выходе нет символов не ASCII cPickle.dumps. Может кто-то также сказать мне, почему cPickle.dump ведет себя так в Python 3?

...