是否可以 ujson.dumps() python 类实例(更快的深度复制)

Posted

技术标签:

【中文标题】是否可以 ujson.dumps() python 类实例(更快的深度复制)【英文标题】:is it possible to ujson.dumps() python class instance (faster deepcopy) 【发布时间】:2018-02-17 18:56:03 【问题描述】:

我正在尝试快速复制一个类实例。 cPickle.loads(cPickle.dumps(),-1) 工作正常,几乎比 copy.deepcopy 快 5 倍,但我 read that ujson is much faster than cPickle。我无法让 ujson 与自定义类一起使用,是否可以这样做?

示例:

import cPickle as pickle
import ujson

class AClass(object):
    def __init__(self):
        print('init')
        self.v = 10
        self.z = [2,3,4]
        self._zdict = dict(zip(self.z,self.z))

a = AClass()
a
#<__main__.AClass at 0x118b1d390>


# does not work with ujson
ua = ujson.dumps(a)
au = ujson.loads(ua)
au
#u'v': 10, u'z': [2, 3, 4]


# but works with pickle
pa = pickle.dumps(a)
ap = pickle.loads(pa)
ap
#<__main__.AClass at 0x117460190>

【问题讨论】:

没有。您可以通过查看ujson.dumps(它只是一个str 对象)的输出来判断它不包含重建源对象所需的信息。它只是一个 JSON 编码器。这就是它比cPickle 更快的部分原因;它不必做那么多。 我认为,您必须开发自己的 JSON 协议。将类实例转储到 JSON 对象中很容易(实际上您转储了__dict__)。但是,加载 JSON 对象并不容易:如何区分 dict 和类实例。没有 JSON 语法。 【参考方案1】:

ujson 没有序列化 对象;它只是将其属性 dict 编码为 JSON 对象。那里没有足够的信息来完整地复制原始对象;最明显的迹象是 ujson.dumps 的输出中没有任何内容记录 a 是哪个类的实例。

usjoncPickle 快得多的原因是cPickle 必须做得更多。

【讨论】:

所以,我猜,cPickle 是我最好的选择【参考方案2】:

一个想法是定义您自己的协议,这是为pickle 描述的概念的基础。 在你的类中定义一个 __getstate____setsatte__ 实例:

class AClass(object):
    def __init__(self, v, z):
        self.v = v
        self.z = z
        self._zdict = dict(zip(self.z, self.z))

    def __repr__(self):
        return repr('v': self.v, 'z': self.z, '_zdict': self._zdict)

    def __getstate__(self):
        return 'v': self.v, 'z': self.z

    def __setstate__(self, state):
        self.__dict__.update(state)
        self._zdict = dict(zip(self.z, self.z))

然后,您可以像这样定义save()load()函数:

import importlib
import json
import io

def save(instance, dst_file):
    data = 
        'module': instance.__class__.__module__,
        'class': instance.__class__.__name__,
        'state': instance.__getstate__()
    json.dump(data, dst_file)


def load(src_file):
    obj = json.load(src_file)
    module_name = obj['module']
    mod = importlib.import_module(module_name)
    cls = getattr(mod, obj['class'])
    instance = cls.__new__(cls)
    instance.__setstate__(obj['state'])
    return instance

简单用法(此处使用StringIO 而不是经典文件):

a_class = AClass(10, [2, 3, 4])
my_file = io.StringIO()
save(a_class, my_file)

print(my_file.getvalue())
# -> "module": "__main__", "class": "AClass", "state": "v": 10, "z": [2, 3, 4]

my_file = io.StringIO(my_file.getvalue())
instance = load(my_file)

print(repr(instance))
# -> 'v': 10, 'z': [2, 3, 4], '_zdict': 2: 2, 3: 3, 4: 4

【讨论】:

以上是关于是否可以 ujson.dumps() python 类实例(更快的深度复制)的主要内容,如果未能解决你的问题,请参考以下文章

是否可以本地编译 Python(除了 pyc 字节码)?

Python判断网络是否可以访问

是否可以指定上一个目录python?

是否可以在 chrome 中运行本机 python 代码?

是否可以使用 Python 创建操作系统? [关闭]

是否可以用 python 连接 MySQL 数据库 [重复]