我有一个对象Traceback (most recent call last):
File ".import.py", line 17, in <module>
modules.append(importlib.import_module(auto,Package=enum))
,其ID,scene_info和rating等字段如下。可以看出,对象具有属于其他类Entry
和Scene
的类型的属性。我想将此对象转换为字典。
Item
Entry(id=None, scene_info=Scene(Recipes=[Item(ID='rec.chicky-nuggies', SpawnerIdx=0), Item(ID='rec.impossible-burger', SpawnerIdx=1)], Decor=[Item(ID='dec.plate-large-orange', SpawnerIdx=2), Item(ID='dec.plate-small-green', SpawnerIdx=3)]), rating=None)
(Pdb) vars(self)
{'id': None, 'scene_info': Scene(Recipes=[Item(ID='rec.chicky-nuggies', SpawnerIndex=0), Item(ID='rec.impossible-burger', SpawnerIdx=1)], Decor=[Item(ID='dec.plate-large-orange', SpawnerIdx=2), Item(ID='dec.plate-small-green', SpawnerIdx=3)]), 'rating': None}
EXPECTED RESULT
我尝试了{'id': None, 'scene_info':{'Recipes': [{'ID': 'rec.chicky-nuggies', 'SpawnerIdx': 0}, {'ID': 'rec.impossible-burger', 'SpawnerIdx': 1}], 'Decor': [{'ID': 'dec.plate-large-orange', 'SpawnerIndex': 2}, {'ID': 'dec.plate-small-green', 'SpawnerIdx': 3}]}, 'rating': None}
,他们只将外部对象转换为dict,而不将内部对象转换为dict。如何转换嵌套的?
答案 0 :(得分:0)
我通常这样做:
class Bar:
# child class
# some init code...
def encode(self):
return vars(self)
class Foo:
# parent class
# some init code...
def encode(self):
return vars(self)
def to_json(self, indent=None):
return json.dumps(self, default=lambda o: o.encode(), indent=indent)
to_json()
将为您提供该类及其嵌套对象的json字符串(如果它们足够简单),您也可以使用棉花糖通过更多控制来做到这一点。您可以只在父类中执行return json.dumps(self, default=lambda o: vars(o), indent=indent)
,而没有encode()
方法,但是使用encode
方法可以自定义输出。
下面是一些随机的,愚蠢的代码,以显示其用法和输出:
import json
class Ingredient:
def __init__(self, name, cost=0):
self.name = name
self.cost = cost
def encode(self):
return vars(self)
class Recipe:
def __init__(self, name, prep_time=0, cook_time=0, ingredients=None,
instructions=None):
self.name = name
self.prep_time = prep_time
self.cook_time = cook_time
self.ingredients = ingredients or []
self.instructions = instructions or {}
def encode(self):
return vars(self)
def to_json(self, indent=None):
return json.dumps(self, default=lambda o: o.encode(), indent=indent)
lettuce = Ingredient('Lettuce', 1.3)
tomato = Ingredient('Tomato', 5.2)
salad = Recipe('Salad', prep_time=5, cook_time=0)
salad.ingredients = [
lettuce,
tomato
]
salad.instructions = {
'Step 1': 'Get the ingredients out',
'Step 2': 'Mix tem together',
'Step 3': 'Eat'
}
print(salad.to_json(4))
输出:
{
"name": "Salad",
"prep_time": 5,
"cook_time": 0,
"ingredients": [
{
"name": "Lettuce",
"cost": 1.3
},
{
"name": "Tomato",
"cost": 5.2
}
],
"instructions": {
"Step 1": "Get the ingredients out",
"Step 2": "Mix tem together",
"Step 3": "Eat"
}
}
答案 1 :(得分:0)
对于类类型(Entry \ Scene \ Item),您可以创建一个函数,该函数以字典形式返回参数。
尝试以下代码:
def getargs(**kwargs):
return kwargs # already a dictionary
Entry = Scene = Item = getargs # all functions do same thing
x = Entry(id=None, scene_info=Scene(Recipes=[Item(ID='rec.chicky-nuggies', SpawnerIdx=0), Item(ID='rec.impossible-burger', SpawnerIdx=1)], Decor=[Item(ID='dec.plate-large-orange', SpawnerIdx=2), Item(ID='dec.plate-small-green', SpawnerIdx=3)]), rating=None)
print(x)
输出
{'id': None, 'scene_info': {'Recipes': [{'ID': 'rec.chicky-nuggies', 'SpawnerIdx': 0}, {'ID': 'rec.impossible-burger', 'SpawnerIdx': 1}], 'Decor': [{'ID': 'dec.plate-large-orange', 'SpawnerIdx': 2}, {'ID': 'dec.plate-small-green', 'SpawnerIdx': 3}]}, 'rating': None}
答案 2 :(得分:0)
首选的方法是使用Tenacious B所述的修饰类定义,但是如果您想要一种快速的解决方案,则可以使用下面所述的 recursive 函数。
def class2dict(instance, built_dict={}):
if not hasattr(instance, "__dict__"):
return instance
new_subdic = vars(instance)
for key, value in new_subdic.items():
new_subdic[key] = class2dict(value)
return new_subdic
示例:
# Class definitions
class Scene:
def __init__(self, time_dur, tag):
self.time_dur = time_dur
self.tag = tag
class Movie:
def __init__(self, scene1, scene2):
self.scene1 = scene1
self.scene2 = scene2
class Entry:
def __init__(self, movie):
self.movie = movie
In [2]: entry = Entry(Movie(Scene('1 minute', 'action'), Scene('2 hours', 'comedy')))
In [3]: class2dict(entry)
Out[3]:
{'movie': {
'scene1': {'time_dur': '1 minute', 'tag': 'action'},
'scene2': {'time_dur': '2 hours', 'tag': 'comedy'}}
}