![](/img/trans.png)
[英]How do I serialize a Java object such that it can be deserialized by pickle (Python)?
[英]How to inspect mystery deserialized object in Python
我正在尝试将JSON重新加载到对象中。 “加载”方法似乎可以正常工作,但该对象似乎没有我期望的属性。
我该如何检查/检查我拥有的对象(这是基于Web的代码)。
results = {"Subscriber": {"firstname": "Neal", "lastname": "Walters"}}
subscriber = json.loads(results)
for item in inspect.getmembers(subscriber):
self.response.out.write("<BR>Item")
for subitem in item:
self.response.out.write("<BR> SubItem=" + subitem)
上面的尝试返回了以下内容:
Item
SubItem=__class__
我不认为它很重要,但对于背景:JSON实际上是从谷歌应用程序引擎的REST Web服务创建网址抓取来使用这个工具创建的: http://code.google.com/p/appengine-rest-服务器 。 正在使用以下定义从数据存储中检索数据:
class Subscriber(db.Model):
firstname = db.StringProperty()
lastname = db.StringProperty()
谢谢,尼尔
更新#1:基本上,我试图将JSON反序列化回一个对象。 从理论上讲,它是从一个对象序列化的,我现在想将其返回到一个对象中。 也许更好的问题是如何做到这一点?
更新2:我试图将一个复杂的程序抽象为几行代码,因此在“伪编码”该程序中犯了一些错误,目的是在此处发布。
这是一个更好的代码示例,现在从我可以在PC上运行的网站上删除。
results = '{"Subscriber": {"firstname": "Neal", "lastname": "Walters"}}'
subscriber = json.loads(results)
for key, value in subscriber.items():
print " %s: %s" %(key, value)
上面的代码运行时,它显示的内容看起来没有比JSON字符串本身更结构化的内容。 它将显示以下内容:订阅者:{u'lastname':u'Walters',u'first'':u'Neal'}
我具有Microsoft的背景知识,所以当我听到序列化/反序列化时,我认为是从对象到字符串,再从字符串回到对象。 因此,如果我先序列化为JSON,然后反序列化,我将得到什么,字典,列表或对象? 实际上,我是从REST Web方法获取JSON的,这代表我为我序列化了对象。
理想情况下,我想要一个与上面的Subscriber类匹配的订阅者对象,理想情况下,我不想编写一次性的自定义代码(即特定于“ Subscriber”的代码),因为我想做同样的事情与其他数十个类别。 如果必须编写一些自定义代码,则需要进行一般性的处理,以便它可以与任何类一起使用。
更新#3:这是为了解释为什么我认为这是必需的工具。 我正在编写一个巨大的应用程序,可能是在Google App Engine(GAE)上。 出于多种原因,我们倾向于REST体系结构,但是一个原因是,我们的Web GUI应该通过REST Web层访问数据存储。 (我更习惯于SOAP,因此切换到REST本身就是一个小挑战)。 因此,获取和更新数据的经典方法之一是通过业务或数据层。 通过使用上面提到的REST实用程序,我可以选择XML或JSON。 我希望在开发大型应用之前先做一个小小的工作原型。 然后,假设我们有一个成功的应用程序,并且GAE将其价格提高了一倍。 然后,我们可以只重写数据层,并采用我们的Python / Django用户层(Web代码),然后在Amazon或其他地方运行它。
如果要执行所有操作,为什么还要将所有内容都作为字典对象。 我不想拥有成熟的课程结构吗? 下一个技巧之一是某种对象关系映射(ORM),这样我们就不必公开确切的数据表,而是公开更多的逻辑层。
我们还希望向可能使用任何语言的付费用户公开RESTful API。 对于他们来说,他们可以使用XML或JSON,并且不会使用此处讨论的序列化例程。
results
您的代码段是字典,而不是字符串,因此json.loads
会引发异常。 如果是固定的,每个subitem
在内环则是一个元组,所以想将它添加到一个字符串作为你正在做会提高其他异常。 我想您已经简化了代码,但是这两个类型错误应该已经表明您简化了太多(并且不正确)。 为什么不使用一个(同样简化的) 工作片段,以及您想要json.loads
的实际字符串,而不是一个无法重现您的问题的字符串? 采取这种行动将使帮助您变得更加容易。
除了查看实际的字符串并显示一些明显的信息(例如type(subscriber)
,基于清晰可见的代码和不足的信息,很难提供更多帮助:-(。
编辑 :在“ update2”中,OP表示
It displays this: Subscriber: {u'lastname': u'Walters', u'firstname': u'Neal'}
...它还能显示什么,祈祷?! 您将键打印为字符串,然后将值打印为字符串-键是字符串,值是另一个字典,所以它当然是“字符串化的”(而且JSON中的所有字符串都是Unicode的-就像在C#中一样或Java,并且您说自己来自MSFT背景,那么为什么这会让您感到惊讶?!)。 str(somedict)
与repr(somedict)
相同,显示键和值的repr
(用大括号括起来,并用冒号和逗号作为适当的分隔符)。
JSON
是一种完全独立于语言的序列化格式,尽管最初以Javascript为中心,但它绝对不知道您希望看到哪些类(如果有)( 当然没有),并且认为它可能是荒谬的:它怎么可能是与语言无关的,如果硬编码的“类”,一个概念,它的概念本身这么多语言,包括JavaScript,甚至没有 ) - ?!因此它使用(在Python方面)的字符串,数字,列表和字典(任何半体面的现代语言都应具有的四种非常基本的数据类型,至少如果没有嵌入适当的语言,至少在某些库中也是如此!)。 当您json.loads
一个字符串时,您总是会得到上述四种数据类型的嵌套组合(所有字符串将是unicode,而所有数字将是浮点数,BTW ;-)。
如果您不知道(并且不想通过某种任意约定或其他方式编码)正在序列化哪个类的实例,但是在反序列化时绝对必须返回类实例(不仅仅是字典等),JSON本身就不能可以帮助您-元信息不能出现在JSON序列化字符串本身中。
如果您对这四种基本类型都没问题,并且只想查看一些比基本类型的默认Python字符串打印更“漂亮”的打印结果,则必须编写自己的递归漂亮打印函数的功能取决于您对“ pretty”的主观定义(我怀疑您是否希望Python自己的pprint
标准库模块超出了您当前的结果;-)。
json仅编码字符串,浮点数,整数,javascript对象(python字典)和列表。
您必须创建一个函数,将返回的字典转换为类,然后使用object_hook
关键字参数以及json字符串将其传递给json.loads
。 继承人一些代码充实了它:
import json
class Subscriber(object):
firstname = None
lastname = None
class Post(object):
author = None
title = None
def decode_from_dict(cls,vals):
obj = cls()
for key, val in vals.items():
setattr(obj, key, val)
return obj
SERIALIZABLE_CLASSES = {'Subscriber': Subscriber,
'Post': Post}
def decode_object(d):
for field in d:
if field in SERIALIZABLE_CLASSES:
cls = SERIALIZABLE_CLASSES[field]
return decode_from_dict(cls, d[field])
return d
results = '''[{"Subscriber": {"firstname": "Neal", "lastname": "Walters"}},
{"Post": {"author": {"Subscriber": {"firstname": "Neal",
"lastname": "Walters"}}},
"title": "Decoding JSON Objects"}]'''
result = json.loads(results, object_hook=decode_object)
print result
print result[1].author
这将处理无需实例化构造函数即可实例化的任何类,而setattr
将适用于该类。
另外,它使用json
。 我没有使用simplejson
这样的YMMV经验,但我听说它们是相同的。
请注意,尽管两个订户对象的值相同,但所得对象却不同。 这可以通过decode_from_dict
类来解决。
我的猜测是loads
正在返回字典。 要遍历其内容,请使用以下方法:
for key, value in subscriber.items():
self.response.out.write("%s: %s" %(key, value))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.