2010-09-09 30 views
5

我很新的python(我使用Python 3),我试图序列化一个字符串和两个列表作为JSon成员的类。我发现python standart中有一个json库,但似乎需要手动实现序列化方法。是否有一个JSon编码器,我可以简单地传递一个对象,并以字符串的形式接收序列化对象,而无需实现序列化方法。 例如:简单的JSON编码与Python

class MyClass: 
    pass 

if __name__ == '__main__': 
    my_name = "me" 
    my_list = {"one","two"} 
    my_obj = MyClass() 
    my_obj.name = my_name; 
    my_obj.my_list = my_list 


    serialized_object = JSONserializer.serialize(my_obj). 

谢谢。

+0

Python版本是否重要?我的意思是,你能用2.x做到这一点吗,但是无法在3.0中做到这一点? – esylvestre 2010-09-09 18:10:50

+0

是的,大多数库似乎已经从2.x更改为3. – 2010-09-09 18:21:39

回答

3

不知道任何事情预先构建的,但你可以写一个,如果你的对象是很简单。重写JSONEncoder中的默认方法以查看inspect.getmembers(obj)(检查是获取__dict__中属性集的更可读的方法)。

#!/usr/bin/env python3 

import inspect 
from json import JSONEncoder 


class TreeNode: 

    def __init__(self, value, left=None, right=None): 
     self.value = value 
     self.left = left 
     self.right = right 


class ObjectJSONEncoder(JSONEncoder): 

    def default(self, reject): 
     is_not_method = lambda o: not inspect.isroutine(o) 
     non_methods = inspect.getmembers(reject, is_not_method) 
     return {attr: value for attr, value in non_methods 
       if not attr.startswith('__')} 


if __name__ == '__main__': 
    tree = TreeNode(42, 
     TreeNode(24), 
     TreeNode(242), 
    ) 
    print(ObjectJSONEncoder().encode(tree)) 

更新: @Alexandre德尚说isroutine作品比对某些输入法。

+0

谢谢你的支持者,除了两件事外,它几乎可以做到这一点。 is_not_method = lambda o:not inspect.ismethod(o)似乎也需要not inspect.isroutine(o)语句。它看起来像在Python中内置的方法是一个极限情况。另外,我的课程需要一个可以序列化的列表。它看起来像列表中的元素不会被序列化。 – 2010-09-10 18:08:37

+0

@Alexandre Deschamps:我不知道你是什么意思......如果你将'__main__'中的这些数字改为数字列表,那么它序列化就好了。 – cdleary 2010-09-10 20:53:35

+0

好吧,我刚刚发现我是问题所在。我使用{}而不是[]来创建列表。正如我所说,我对这门语言很陌生。它工作正常。只要将“not inspect.isroutine”添加到您的示例中,以防其他人需要它。非常感谢您的时间。 – 2010-09-10 21:38:54

0

JSONEncoder这个班怎么样?

更新

我一定跳过了有关数据的一部分被包含在一个类中。如果你想在不需要扩展编码器的情况下完成任意Python对象的序列化,那么也许你可以使用picklejson的组合。酸洗时,使用protocol = 0将数据序列化为可读的ASCII。

+0

不过,我需要编码一个类,而不仅仅是一个简单的类型或数组。这个类似乎需要一个手动定义的序列化方法来序列化一个类。也许我错了,因为我对这门语言很陌生,但是当我测试时,我就是这样。 – 2010-09-09 18:28:32

+0

@Alexandre - 更新了我的答案 – 2010-09-09 18:53:51

+0

'人类可读的pickle'的想法是:'(i__main__ 地图 P0 (DP1 S'towers' P2 (LP3 (i__main__ 塔 P4 (DP5 S'attack ' P6 I10 sbasS'creeps' P7 (LP8在列表' P9 S'one串蠕变asb.'相比JSON,即几乎不人类可读的。 – Pat 2012-03-29 02:14:02

4

您如何期待json库知道如何序列化任意类?

在你的情况,如果你的类是很简单的,你也许可以逃脱喜欢的东西

foo = FooObject() # or whatever 
json_string = json.dumps(foo.__dict__) 

只序列化对象的成员。然后

反序列化将需要像

foo_data = json.loads(json_string) 
foo = FooObject(**foo_data) 
+0

那不,似乎不工作,因为我的班级有两个成员,这是一个字符串和字符串列表 – 2010-09-10 18:05:30

+0

它适用于我:http://gist.github.com/574291。如果你的对象真的只有两个成员,一个字符串和一个字符串列表,那么序列化将起作用。我使用的反序列化技术依赖于你的对象的'__init__'函数来获取与成员相同名称的参数。查看上面的要点来了解一个工作示例。 – 2010-09-10 20:13:04

+0

@WillMcCutchen感谢您使用'dict'的灵感。我想做类似的事情,虽然我的对象(来自SOAP请求)没有'__dict__'方法,调用'dict(soapObj)'给了我一个很好的打印的JSON字符串。我也是Python新手,这不是一个明显的技术,所以我很高兴你提到它! – Pat 2012-03-29 02:05:17