Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python结构属性到字典_Python_Google App Engine - Fatal编程技术网

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