如何检查Python中的神秘反序列化对象 [英] How to inspect mystery deserialized object in Python

查看:120
本文介绍了如何检查Python中的神秘反序列化对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将JSON加载回对象中。 加载方法似乎没有错误,但该对象似乎没有我期望的属性。

我该如何去检查/检查我拥有的对象(这是基于web的代码)。

  results = {Subscriber:{firstname:Neal,lastname:Walters}} 
订阅者= json.loads(结果)


用于inspect.getMembers(订阅者)中的项目:
self.response.out.write(< BR>项目)
子项目中的项目:
self.response.out.write(<& nbsp; SubItem =+子项目)



上面的尝试返回了这个结果:

  Item 
SubItem = __ class__

我不认为这很重要,但是对于上下文:
JSON实际上来自Google App Engine中的urlfetch,使用此实用程序创建的
a其他Web服务:
http://code.google.com/p/appengine-rest-server
使用此定义从数据存储中检索数据:

$ $ $ $ $ $ $ $ $ $ $> $ Subscriber(db.Model):
firstname = db.StringProperty()
lastname = db.StringProperty()


Neal


更新#1:基本上我试图将JSON反序列化回一个对象。
理论上它是从一个对象序列化的,我现在想把它重新放回一个对象中。
也许更好的问题是如何做到这一点?

更新#2:我试图将一个复杂的程序抽象为几行代码,所以我在为其目的伪编码时犯了一些错误张贴在这里。

这里有一个更好的代码示例,现在我可以在网站上运行PC。

  results ='{Subscriber:{firstname:Neal,lastname:Walters}} '
订阅者= json.loads(结果)
for key,subscriber.items()中的值:
print%s:%s%(key,value)

上面的运行,它显示的内容看起来不像JSON字符串本身的结构。它显示:
订阅者:{u'lastname':u'Walters',u'firstname':u'Neal'}



我有更多一个微软的背景,所以当我听到序列化/反序列化时,我想从一个对象到一个字符串,从一个字符串回到一个对象。所以如果我序列化为JSON,然后反序列化,我会得到什么,字典,列表或对象?实际上,我从REST webmethod获取JSON,也就是我代表我的序列化对象。

理想情况下,我需要一个与上面的Subscriber类匹配的订阅者对象,理想情况下,我不想写一次性自定义代码(即代码是特定的到订阅者),因为我想对其他几十个类做同样的事情。如果我必须编写一些自定义代码,那么我需要一般地完成它,以便它可以与任何类一起使用。

更新#3:这是为了解释为什么我认为这是一个需要的工具。我正在编写一个巨大的应用程序,可能在Google App Engine(GAE)上。我们倾向于REST体系结构的原因有很多,但其中一个原因是我们的Web GUI应该通过REST Web层访问数据存储。 (我更习惯于使用SOAP,因此切换到REST本身就是一个小挑战)。因此,获取和更新数据的经典方法之一是通过业务或数据层。通过使用上面提到的REST实用程序,我可以选择XML或JSON。我希望在开发这个庞大的应用程序之前,先制作一个两者的小型工作原型)。那么,假设我们有一个成功的应用程序,GAE将其价格翻倍。然后,我们可以重新编写数据层,并使用我们的Python / Django用户层(网络代码),并在Amazon或其他地方运行它。

如果我要做所有这些,为什么我要把所有东西都当成字典对象。我不想要全面的阶级结构的力量吗?下一个技巧之一就是对象关系映射(ORM),以便我们不一定公开我们的确切数据表,但更多的是逻辑层。

我们也希望将RESTful API公开给可能使用任何语言的付费用户。对于他们来说,他们可以使用XML或JSON,他们不会使用这里讨论的序列化例程。

解决方案

$ b $ json只编码字符串,浮点数,整数,JavaScript对象(python dicts)和列表。 b

您必须创建一个函数将返回的字典转换为类,然后使用<$ c $将它传递给 json.loads c> object_hook 关键字参数以及json字符串。下面是一些代码:

  import json 

class订阅者(对象):
firstname = None
lastname = None


class Post(object):
author = None
title = None


def decode_from_dict(cls,vals):
obj = cls()
for vals.items():
setattr(obj,key,val)
return obj


SERIALIZABLE_CLASSES = {'Subscriber':Subscriber,
'Post':Post}

def decode_object(d) :
表示字段在d:
如果字段在SERIALIZABLE_CLASSES中:
cls = SERIALIZABLE_CLASSES [字段]
返回decode_from_dict(cls,d [字段])
返回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
打印结果[1] .author

这将处理任何可以实例化的类,构造函数,并且其中 setattr 将可用。

另外,它使用 json 。我对 simplejson 没有经验,所以YMMV,但我听说他们是相同的。



请注意,尽管两个订户对象是相同的,所得到的对象不是。这可以通过记忆 decode_from_dict 类来解决。


I'm trying to load JSON back into an object. The "loads" method seems to work without error, but the object doesn't seem to have the properties I expect.

How can I go about examining/inspecting the object that I have (this is web-based code).

  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>&nbsp;SubItem=" + subitem)

The attempt above returned this:

   Item
     SubItem=__class__

I don't think it matters, but for context: The JSON is actually coming from a urlfetch in Google App Engine to a rest web service created using this utility: http://code.google.com/p/appengine-rest-server. The data is being retrieved from a datastore with this definition:

class Subscriber(db.Model):
    firstname    = db.StringProperty()
    lastname     = db.StringProperty()

Thanks, Neal

Update #1: Basically I'm trying to deserialize JSON back into an object. In theory it was serialized from an object, and I want to now get it back into an object. Maybe the better question is how to do that?

Update #2: I was trying to abstract a complex program down to a few lines of code, so I made a few mistakes in "pseudo-coding" it for purposes of posting here.

Here's a better code sample, now take out of website where I can run on PC.

results = '{"Subscriber": {"firstname": "Neal", "lastname": "Walters"}}'
subscriber = json.loads(results)
for key, value in subscriber.items():
    print " %s: %s" %(key, value)

The above runs, what it displays doesn't look any more structured than the JSON string itself. It displays this: Subscriber: {u'lastname': u'Walters', u'firstname': u'Neal'}

I have more of a Microsoft background, so when I hear serialize/deserialize, I think going from an object to a string, and from a string back to an object. So if I serialize to JSON, and then deserialize, what do I get, a dictionary, a list, or an object? Actually, I'm getting the JSON from a REST webmethod, that is on my behalf serializing my object for me.

Ideally I want a subscriber object that matches my Subscriber class above, and ideally, I don't want to write one-off custom code (i.e. code that would be specific to "Subscriber"), because I would like to do the same thing with dozens of other classes. If I have to write some custom code, I will need to do it generically so it will work with any class.

Update #3: This is to explain more of why I think this is a needed tool. I'm writing a huge app, probably on Google App Engine (GAE). We are leaning toward a REST architecture for several reasons, but one is that our web GUI should access the data store via a REST web layer. (I'm a lot more used to SOAP, so switching to REST is a small challenge in itself). So one of the classic ways of getting and update data is through a business or data tier. By using the REST utility mention above, I have the choice of XML or JSON. I'm hoping to do a small working prototype of both before we develop the huge app). Then, suppose we have a successful app, and GAE doubles it prices. Then we can rewrite just the data tier, and take our Python/Django user tier (web code), and run it on Amazon or somewhere else.

If I'm going to do all that, why would I want everything to be dictionary objects. Wouldn't I want the power of full-blown class structure? One of the next tricks is sort of an object relational mapping (ORM) so that we don't necessarily expose our exact data tables, but more of a logical layer.

We also want to expose a RESTful API to paying users, who might be using any language. For them, they can use XML or JSON, and they wouldn't use the serialize routine discussed here.

解决方案

json only encodes strings, floats, integers, javascript objects (python dicts) and lists.

You have to create a function to turn the returned dictionary into a class and then pass it to a json.loads using the object_hook keyword argument along with the json string. Heres some code that fleshes it out:

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

This will handle any class that can be instantiated without arguments to the constructor and for which setattr will work.

Also, this uses json. I have no experience with simplejson so YMMV but I hear that they are identical.

Note that although the values for the two subscriber objects are identical, the resulting objects are not. This could be fixed by memoizing the decode_from_dict class.

这篇关于如何检查Python中的神秘反序列化对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆