2

我绝不是 Python Guru,但我知道自己的方式。然而,在过去的两个小时里,我一直在抨击以下内容:

我正在使用 json.loads() 函数解析来自 WCF Web 服务的 JSON 响应。结果是我在整个应用程序中使用的 Python 字典。但是,我现在需要混淆 id、reseller_id 等以便在 HTTP GET 请求中使用。

这是一个响应示例:(注意,我有很多这样的响应,所以我正在寻找一个通用的解决方案。)我想用 id 值的哈希替换任何 id 的值

{
    "token":"String content",
    "user":{
        "distributor":{
            "email":"String content",
            "id":2147483647,
            "name":"String content"
        },
        "email":"String content",
        "first_name":"String content",
        "id":2147483647,
        "last_name":"String content",
        "reseller":{
            "email":"String content",
            "id":2147483647,
            "name":"String content",
            "portal_css":"String content",
            "portal_logo":"String content",
            "portal_name":"String content",
            "portal_url":"String content"
        },
        "role":2147483647
    }
}

我使用以下代码尝试了各种策略:

result = json.loads(json_result, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))

def fun(d):
    if 'id' in d:
        yield d['id']
    for k in d:
        if isinstance(d[k], list):
            for i in d[k]:
                for j in fun(i):
                    yield j

我无法让它正常工作。所以:

问题 1: 我可以将 json 转换为(匿名)Python 对象吗?如何转换?

问题 2: 我可以就地编辑结果字典吗?

问题3: 当一切都失败时;有人知道如何实现这一目标吗?

非常感谢!

4

3 回答 3

3
json.loads(data)

解析 json 字符串data并返回一个 Python dict,我猜你可以称之为匿名,直到你将它分配给一个变量:

d = json.loads(data)

然后,您可以就地修改字典。假设您的所有响应具有相同的结构,您可以散列id如下:

d["user"]["id"] = your_hash_function(d["user"]["id"])
于 2013-04-16T15:04:34.010 回答
1

是的。 json.loads根据实际的 json 对象返回一个 Python 对象。查看转换表以获取更多详细信息。无需像在 .Net 中那样寻找特殊的匿名对象。

result = json.loads(json_text)

您可以result就地编辑它:

result['user']['id'] = 'some_new_value' 

object_pairs_hook解析 json 时尝试参数:

def hide_ids(o):
    d = dict(o)
    if 'id' in d:
        d['id'] = '----{}----'.format(d['id'])
    return d

result = json.loads(json_text, object_pairs_hook=hide_ids)

只需使用您喜欢的混淆逻辑进行修改,您就可以开始使用了。

于 2013-04-16T15:28:21.650 回答
1

这是我快速整理的解决方案。它通过您的字典递归并在键为 id 时替换值。这不是最终解决方案,因为它不支持列表,但我确定这是否适合您,您可以从那里获取它吗?

def f(d):
    _dict = {}
    for k, v in d.items():
        if isinstance(v, dict):
            _dict.update({k: f(v)})
        else:
            if k == 'id':
                print 'id found', v
                v = EncryptValueHere(v)
            _dict.update({k:v})

    return _dict
于 2013-04-16T15:11:36.870 回答