在python中序列化suds对象

2024-04-20 08:34:53 发布

您现在位置:Python中文网/ 问答频道 /正文

好吧,我正在努力改进python,所以我不确定这是正确的方法来开始我的工作,但这是我目前的问题。。。

我需要通过SOAP方法获取一些信息,现在只使用部分信息,但要存储整个结果以备将来使用(我们需要尽可能少地使用服务)。查找访问该服务的最佳方法时,我认为sud是一种方法,它很简单,而且工作起来很有魅力,可以获取数据。但现在我想以某种方式保存结果,最好是序列化/保存在数据库中,以便以后可以将其提取出来并使用相同的结果。

最好的方法是什么,pickle/json看起来不是一个选项?谢谢!

更新 阅读How can I pickle suds results?上的最上面的答案可以让我更好地理解为什么这不是一个选项,我想我被困在重新创建一个基本对象和我需要的信息?


Tags: 方法信息数据库json序列化选项方式can
3条回答

是的,我确认了我在你提到的答案中给出的解释——动态生成的类不容易挑选(也不容易序列化),你需要提取所有的状态信息,picklethatstate,如果你真的坚持使用它,在检索时重建棘手的sudsobject;-)。

我一直在使用以下方法将Suds对象转换为JSON:

from suds.sudsobject import asdict

def recursive_asdict(d):
    """Convert Suds object into serializable format."""
    out = {}
    for k, v in asdict(d).iteritems():
        if hasattr(v, '__keylist__'):
            out[k] = recursive_asdict(v)
        elif isinstance(v, list):
            out[k] = []
            for item in v:
                if hasattr(item, '__keylist__'):
                    out[k].append(recursive_asdict(item))
                else:
                    out[k].append(item)
        else:
            out[k] = v
    return out

def suds_to_json(data):
    return json.dumps(recursive_asdict(data))

我做了一个sud对象维护的虚拟类的实现,然后能够序列化。FakeSudsInstance的行为类似于原始Suds对象实例,请参见以下内容:

from suds.sudsobject import Object as SudsObject

class FakeSudsNode(SudsObject):

    def __init__(self, data):
        SudsObject.__init__(self)
        self.__keylist__ = data.keys()
        for key, value in data.items():
            if isinstance(value, dict):
                setattr(self, key, FakeSudsNode(value))
            elif isinstance(value, list):
                l = []
                for v in value:
                    if isinstance(v, list) or isinstance(v, dict):
                        l.append(FakeSudsNode(v))
                    else:
                        l.append(v)
                setattr(self, key, l)
            else:
                setattr(self, key, value)


class FakeSudsInstance(SudsObject):

    def __init__(self, data):
        SudsObject.__init__(self)
        self.__keylist__ = data.keys()
        for key, value in data.items():
            if isinstance(value, dict):
                setattr(self, key, FakeSudsNode(value))
            else:
                setattr(self, key, value)

    @classmethod
    def build_instance(cls, instance):
        suds_data = {}
        def node_to_dict(node, node_data):
            if hasattr(node, '__keylist__'):
                keys = node.__keylist__
                for key in keys:
                    if isinstance(node[key], list):
                        lkey = key.replace('[]', '')
                        node_data[lkey] = node_to_dict(node[key], [])
                    elif hasattr(node[key], '__keylist__'):
                        node_data[key] = node_to_dict(node[key], {})
                    else:
                        if isinstance(node_data, list):
                            node_data.append(node[key])
                        else:
                            node_data[key] = node[key]
                return node_data
            else:
                if isinstance(node, list):
                    for lnode in node:
                        node_data.append(node_to_dict(lnode, {}))
                    return node_data
                else:
                    return node
        node_to_dict(instance, suds_data)
        return cls(suds_data)

现在,在一个suds调用之后,例如下面:

# Now, after a suds call, for example below
>>> import cPickle as pickle
>>> suds_intance = client.service.SomeCall(account, param)
>>> fake_suds = FakeSudsInstance.build_instance(suds_intance)
>>> dumped = pickle.dumps(fake_suds)
>>> loaded = pickle.loads(dumped)

我希望有帮助。

相关问题 更多 >