<p>我将<a href="https://stackoverflow.com/a/8230373/1067132">Raymond Hettinger's solution</a>改编为python 3。</p>
<p>以下是改变的地方:</p>
<ul>
<li><code>unicode</code>消失</li>
<li>用<code>super()</code>更新了对父级<code>default</code>的调用</li>
<li>使用<code>base64</code>将<code>bytes</code>类型序列化为<code>str</code>(因为python 3中的<code>bytes</code>似乎无法转换为JSON)</li>
</ul>
<pre class="lang-python prettyprint-override"><code>from decimal import Decimal
from base64 import b64encode, b64decode
from json import dumps, loads, JSONEncoder
import pickle
class PythonObjectEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, (list, dict, str, int, float, bool, type(None))):
return super().default(obj)
return {'_python_object': b64encode(pickle.dumps(obj)).decode('utf-8')}
def as_python_object(dct):
if '_python_object' in dct:
return pickle.loads(b64decode(dct['_python_object'].encode('utf-8')))
return dct
data = [1,2,3, set(['knights', 'who', 'say', 'ni']), {'key':'value'}, Decimal('3.14')]
j = dumps(data, cls=PythonObjectEncoder)
print(loads(j, object_hook=as_python_object))
# prints: [1, 2, 3, {'knights', 'who', 'say', 'ni'}, {'key': 'value'}, Decimal('3.14')]
</code></pre>