Python结构属性到字典
我的模型都有一个将模型转换为字典的方法:Python结构属性到字典,python,google-app-engine,Python,Google App Engine,我的模型都有一个将模型转换为字典的方法: def to_dict(model): output = {} SIMPLE_TYPES = (int, long, float, bool, dict, basestring, list) for key, prop in model._properties.iteritems(): value = getattr(model, key) if value is None:
def to_dict(model):
output = {}
SIMPLE_TYPES = (int, long, float, bool, dict, basestring, list)
for key, prop in model._properties.iteritems():
value = getattr(model, key)
if value is None:
continue
if isinstance(value, SIMPLE_TYPES):
output[key] = value
elif isinstance(value, datetime.date):
dateString = value.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
output[key] = dateString
elif isinstance(value, ndb.Model):
output[key] = to_dict(value)
else:
raise ValueError('cannot encode ' + repr(prop))
return output
现在,我的一个模型,X
,有一个LocalStructuredProperty
:
metaData = ndb.LocalStructuredProperty(MetaData, repeated=True)
因此,repeated=True意味着这将是元数据对象的列表MetaData
是另一个模型,它也有相同的to_dict
方法
但是,当我调用json.dumps(xInstance.to_dict())
时,我得到一个异常:
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: MetaData(count=0, date=datetime.datetime(2012, 9, 19, 2, 46, 56, 660000), unique_id=u'8E2C3B07A06547C78AB00DD73B574B8C') is not JSON serializable
如何处理这个问题?序列化所需做的就是实现一个函数
def default_encode(obj):
return obj.to_dict()
然后用
json.dumps(X.to_dict(), default=default_encode)
我找到了解决问题的方法:在X类中,将其添加到to_dict()方法中:
虽然我不确定如何自动处理这种情况,因为它不是基于键,而是每当遇到自定义对象列表时,它首先将列表中的每个对象转换为_dict()。如果您想在到_dict()以及序列化为JSON之前处理这个问题,您只需在
to_dict()
中再添加几个案例即可。首先,你说上面的定义是一种方法。我会让它委托给一个函数或staticmethod,这样你就可以调用ints
之类的东西,而不用先检查类型。这样代码就会变得更好
def coerce(value):
SIMPLE_TYPES = (int, long, float, bool, basestring)
if value is None or isinstance(value, SIMPLE_TYPES):
return value
elif isinstance(value, datetime.date):
return value.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
elif hasattr(value, 'to_dict'): # hooray for duck typing!
return value.to_dict()
elif isinstance(value, dict):
return dict((coerce(k), coerce(v)) for (k, v) in value.items())
elif hasattr(value, '__iter__'): # iterable, not string
return map(coerce, value)
else:
raise ValueError('cannot encode %r' % value)
然后将其插入您的以记录方法本身:
def to_dict(model):
output = {}
for key, prop in model._properties.iteritems():
value = coerce(getattr(model, key))
if value is not None:
output[key] = value
return output
不清楚您的定义是如何成为实例方法的。还不清楚您试图序列化什么。如果您试图序列化方法X.to_dict
,这肯定会失败。几乎可以肯定的是,他们在发布问题时忘记了括号。很抱歉,应该是Xistance。to_dict()而不是X.to_dict…但这只是一个输入错误,因此,这个问题在现实生活中仍然存在。请参阅我的最新评论。我不知道这是否有区别,但我不确定你是否理解我的问题。问题在于,当X模型的to_dict()方法遇到元数据列表时,它不会序列化列表中的对象,而只是将列表放入字典中。我希望X实例方法能够处理这样的情况,即属性是元数据列表,在这种情况下,也要确保对元数据对象调用_dict()。你明白我的意思了吗?elif hasattr(value,'to _dict'):
如何工作?它检查是否有一个名为to_dict()?Yep的方法。如果它在那里,就叫它。它是一种“隐式接口”,python中的很多东西都是这样工作的,但如果名称稍长一些,可能会减少冲突的可能性。或者您可以将其更改回iInstance检查。
def to_dict(model):
output = {}
for key, prop in model._properties.iteritems():
value = coerce(getattr(model, key))
if value is not None:
output[key] = value
return output