在Python中序列化函数的源代码

2 投票
4 回答
2342 浏览
提问于 2025-04-17 23:43

我正在尝试把一段代码转换成可以发送的json格式...

def f(x): return x*x
def fi(x): return int(x[0])

code_string = marshal.dumps(fi.func_code)

jsn = {"code":code_string)
json.dumps(jsn) # doesnt work if code_string is from fi

所以... 上面的代码块在我的函数是 f(x) 的时候可以正常工作

但是在函数是 fi(x) 的时候就不行了

最开始出现的错误是:

Traceback (most recent call last):
  File "/home/mohitdee/Documents/python_scala/rdd.py", line 41, in <module>
    send_data(json.dumps(jsn))
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x83 in position 32: invalid start byte
[48001 refs]

我该如何在python中解决这个问题呢

4 个回答

2

试着用base64或者其他类似的编码方法来处理它。

2

使用 pickle(或者 cPickle):

pickle模块实现了一种基本但强大的算法,用于将Python对象结构进行序列化和反序列化。

>>> import cPickle
>>> import json
>>> def fi(x):
...     return int(x[0])
... 
>>> fi(['1'])
1
>>> code_string = cPickle.dumps(fi)
>>> jsn = {"code": code_string}
>>> serialized = json.dumps(jsn)

>>> deserialized = json.loads(serialized)
>>> f = cPickle.loads(str(deserialized['code']))
>>> print f(['1'])
1
3

你可以用 cloud 库里的 pickle 功能,把各种活的对象,包括函数,变成可以保存和传输的格式。

import cloud, pickle

def serialize(func):
    return cloud.serialization.cloudpickle.dumps(func)

def deserialize(string):
    return pickle.loads(string)
6

Marshall是一种二进制协议,也就是说它是一堆字节,这些字节有着非常特殊的解释方式。它不是文本,也不符合任何特定的文本编码。大部分情况下,它只是一个比特的序列。如果你一定要把这些内容嵌入到像JSON这样的文本协议中,就需要对那些在相关编码中不合法的字符进行转义(为了安全起见,可以假设只用ASCII的一部分)。最常用的解决办法是base64

import base64

code_string = marshal.dumps(fi.func_code)
code_base64 = base64.b64encode(code_string)

jsn = {"code": code_base64}

撰写回答