Sha*_*obe 32 python python-2.6
我正在尝试将数据从简单的对象图转换为字典.我不需要类型信息或方法,我不需要能够再次将它转换回对象.
我发现这个问题是关于从对象的字段创建字典,但它不会递归地执行.
对于python来说相对较新,我担心我的解决方案可能是丑陋的,或者说是unpythonic,或者是以某种模糊的方式打破,或者只是简单的旧NIH.
我的第一次尝试似乎工作,直到我尝试使用列表和字典,并且检查传递的对象是否有内部字典似乎更容易,如果没有,只是将其视为一个值(而不是做所有的实例检查) ).我以前的尝试也没有递归到对象列表中:
def todict(obj):
if hasattr(obj, "__iter__"):
return [todict(v) for v in obj]
elif hasattr(obj, "__dict__"):
return dict([(key, todict(value))
for key, value in obj.__dict__.iteritems()
if not callable(value) and not key.startswith('_')])
else:
return obj
Run Code Online (Sandbox Code Playgroud)
这似乎工作得更好,不需要例外,但我仍然不确定这里是否有案例,我不知道它在哪里落下.
任何建议将不胜感激.
Sha*_*obe 42
我自己的尝试和来自Anurag Uniyal和Lennart Regebro的答案的线索的合并最适合我:
def todict(obj, classkey=None):
if isinstance(obj, dict):
data = {}
for (k, v) in obj.items():
data[k] = todict(v, classkey)
return data
elif hasattr(obj, "_ast"):
return todict(obj._ast())
elif hasattr(obj, "__iter__") and not isinstance(obj, str):
return [todict(v, classkey) for v in obj]
elif hasattr(obj, "__dict__"):
data = dict([(key, todict(value, classkey))
for key, value in obj.__dict__.items()
if not callable(value) and not key.startswith('_')])
if classkey is not None and hasattr(obj, "__class__"):
data[classkey] = obj.__class__.__name__
return data
else:
return obj
Run Code Online (Sandbox Code Playgroud)
Arc*_*edi 13
一个行代码,用于递归地将对象转换为json
import json
def get_json(object):
return json.loads(
json.dumps(object, default=lambda o: getattr(o, '__dict__', str(o)))
)
object = SomeClass()
print("Json = ", get_json(object))
Run Code Online (Sandbox Code Playgroud)
我不知道检查basetring或object的目的是什么?还字典将不包含任何可调用,除非你有指向这样的可调用属性,但在这种情况下是不是对象的一部分?
因此,不是检查各种类型和值,而是让todict转换对象,如果它引发异常,请使用原始值.
如果obj没有dict 例如,todict只会引发异常
class A(object):
def __init__(self):
self.a1 = 1
class B(object):
def __init__(self):
self.b1 = 1
self.b2 = 2
self.o1 = A()
def func1(self):
pass
def todict(obj):
data = {}
for key, value in obj.__dict__.iteritems():
try:
data[key] = todict(value)
except AttributeError:
data[key] = value
return data
b = B()
print todict(b)
Run Code Online (Sandbox Code Playgroud)
它打印{'b1':1,'b2':2,'o1':{'a1':1}}可能还有其他一些需要考虑的情况,但它可能是一个好的开始
特殊情况, 如果一个对象使用插槽,那么你将无法获得dict,例如
class A(object):
__slots__ = ["a1"]
def __init__(self):
self.a1 = 1
Run Code Online (Sandbox Code Playgroud)
修复插槽的情况可以是使用dir()而不是直接使用dict