21

jsonpickleを使用してPythonオブジェクトをファイルに書き込むための次の簡単なメソッドがあります。

def json_serialize(obj, filename, use_jsonpickle=True):
    f = open(filename, 'w')
    if use_jsonpickle:
        import jsonpickle
        json_obj = jsonpickle.encode(obj)
        f.write(json_obj)
    else:
        simplejson.dump(obj, f) 
    f.close()

def json_load_file(filename, use_jsonpickle=True):
    f = open(filename)
    if use_jsonpickle:
        import jsonpickle
        json_str = f.read()
        obj = jsonpickle.decode(json_str)
    else:
        obj = simplejson.load(f)
    return obj

問題は、これらを使用するたびに、オブジェクトを辞書( "py / object": "my_module.MyClassName"などのフィールドを持つ)としてロードしますが、生成に使用されたタイプの実際のPythonオブジェクトとしてはロードしないことです。 json文字列。jsonpickleが実際にロードされた文字列をオブジェクトに変換するようにするにはどうすればよいですか?

これを例で説明するために、次のことを考慮してください。

class Foo:
    def __init__(self, hello):
    self.hello = hello

# make a Foo obj
obj = Foo("hello world")
obj_str = jsonpickle.encode(obj)
restored_obj = jsonpickle.decode(obj_str)
list_objects = [restored_obj]
# We now get a list with a dictionary, rather than
# a list containing a Foo object
print "list_objects: ", list_objects

これにより、次のようになります。

list_objects:  [{'py/object': 'as_events.Foo', 'hello': 'hello world'}]

[Foo()]のようなものではなく。どうすればこれを修正できますか?

ありがとう。

4

3 に答える 3

24

正解は、私はから継承していなかったということでしたobject。から継承しobjectないと、jsonpickleは、コンストラクターで1つ以上の引数を取るクラスを正しくデコードできないようです。私は決して専門家ではありませんが、クラス宣言でFoo(object):はなくそれを作成することでFoo:修正されました。

于 2010-03-09T00:27:23.933 に答える
4

でそれを確認してuse_jsonpickle == Trueくださいjson_load_file()。を使用してシリアル化し、を使用jsonpickleしてロードしているようですjson

>>> import jsonpickle
>>> class A(object):
...    def __init__(self, name):
...       self.name = name
... 
>>> js = jsonpickle.encode(A('abc'))
>>> js
'{"py/object": "__main__.A", "name": "abc"}'     # <-- json string
>>> a = jsonpickle.decode(js)
>>> a
<__main__.A object at 0x7f826a87bd90>            # <-- python object
>>> a.name
u'abc'
>>> import json
>>> b = json.loads(js)
>>> b
{u'py/object': u'__main__.A', u'name': u'abc'}    # <-- dictionary

オブジェクトタイプが使用可能であることを確認してください

>>> del A
>>> c = jsonpickle.decode(js)                  # no type available
>>> c
{u'py/object': u'__main__.A', u'name': u'abc'}
>>> type(c)
<type 'dict'>
>>> class A(object):
...    def __init__(self, name):
...        self.name = name
... 
>>> d = jsonpickle.decode(js)                   # type is available
>>> d
<__main__.A object at 0x7f826a87bdd0>
>>> type(d)
<class '__main__.A'>
于 2010-03-07T22:22:50.203 に答える
0

この投稿の時点で、シリアル化されたオブジェクトが内部クラスである場合にエンコードが間違ってしまうバグがあります。クラスが別のクラス内にないことを確認してください。メンテナに問題を提起しました。https://github.com/jsonpickle/jsonpickle/issues/210

于 2018-07-02T09:45:43.520 に答える