简体   繁体   English

将嵌套的 Python 对象转换为字典的最经济的方法是什么?

[英]What is the most economical way to convert nested Python objects to dictionaries?

I have some SQLAlchemy objects which contain lists of more SQLAlchemy objects, and so on (for about 5 levels).我有一些 SQLAlchemy 对象,其中包含更多 SQLAlchemy 对象的列表,依此类推(大约 5 个级别)。 I wish to convert all the objects to dictionaries.我希望将所有对象转换为字典。

I can convert an object to a dictionary by using the __dict__ property, no problem.我可以使用__dict__属性将对象转换为字典,没问题。 However, I'm having trouble figuring out the best way to convert all the nested objects as well, without having to do each level explicitly.但是,我在找出转换所有嵌套对象的最佳方法时遇到了麻烦,而不必明确地执行每个级别。

So far, this is the best I can come up with, but it doesn't recurse properly.到目前为止,这是我能想到的最好的方法,但它不能正确递归。 It basically breaks after one pass, so there's clearly something wrong with my logic.它基本上在一次通过后就中断了,所以我的逻辑显然有问题。 Can you see what's wrong with it??你能看出它有什么问题吗??

I am hoping to do:我希望这样做:

all_dict = myDict(obj.__dict__)

def myDict(d):
    for k,v in d.items():
        if isinstance(v,list):
            d[k] = [myDict(i.__dict__) for i in v]
        else:
            d[k] = v
    return d

Life Hack:生活黑客:

def to_dict(obj):
    return json.loads(json.dumps(obj, default=lambda o: o.__dict__))

This leverages the default input of the json.dumps() method (or json.dump() ) by returning the __dict__ representation of the objects that are not serializable.这通过返回不可序列化对象的__dict__表示来利用json.dumps()方法(或json.dump() )的default输入。 Note that this may not work when objects contain non-standard data structures (such as NumPy or Pandas).请注意,当对象包含非标准数据结构(例如 NumPy 或 Pandas)时,这可能不起作用。 The following is the description from the documentation of json.dump :以下是json.dump文档中的描述

If specified, default should be a function that gets called for objects that can't otherwise be serialized.如果指定,默认值应该是一个函数,该函数会为无法以其他方式序列化的对象调用。 It should return a JSON encodable version of the object or raise a TypeError.它应该返回对象的 JSON 可编码版本或引发 TypeError。 If not specified, TypeError is raised.如果未指定,则引发 TypeError。

I am not sure if I understood exactly what you want - but if I got, this function can do what you want: It does search recursively on an object's attributes, yielding a nested dictionary + list structure, with the ending points being python objects not having a __dict__ attribute - which in SQLAlchemy's case are likely to be basic Python types like numbers and strings.我不确定我是否完全理解你想要的东西 - 但如果我明白了,这个函数可以做你想做的事:它确实递归搜索对象的属性,产生嵌套字典 + 列表结构,结束点不是 python 对象具有 __dict__ 属性 - 在 SQLAlchemy 的情况下,它可能是基本的 Python 类型,如数字和字符串。 (If that fails, replacing the "hasattr dict" test for soemthing more sensible should fix the code for your needs. (如果失败,更换“hasattr dict”测试更明智应该修复您需要的代码。

def my_dict(obj):
    if not  hasattr(obj,"__dict__"):
        return obj
    result = {}
    for key, val in obj.__dict__.items():
        if key.startswith("_"):
            continue
        element = []
        if isinstance(val, list):
            for item in val:
                element.append(my_dict(item))
        else:
            element = my_dict(val)
        result[key] = element
    return result

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM