2

有没有办法以干净优雅的方式检查列表理解的每个元素?

例如,如果我有一些可能有也可能没有'loc'属性的数据库结果,有没有办法让以下代码运行而不会崩溃?

db_objs    = SQL("query")
top_scores = [{"name":obj.name, "score":obj.score, "latitude":obj.loc.lat, "longitude":obj.loc.lon} for obj in db_objs]

如果有任何方法可以将这些字段填充为 None 或空字符串或任何内容,那将非常好。Python 往往是一个神奇的东西,所以如果你们有任何明智的建议,将不胜感激。

4

3 回答 3

3

干净统一的解决方案:

from operator import attrgetter as _attrgetter

def attrgetter(attrname, default=None):
    getter = _attrgetter(attrname)
    def wrapped(obj):
        try:
            return getter(obj)
        except AttributeError:
            return default

    return wrapped

GETTER_MAP =  {
    "name":attrgetter('name'),
    "score":attrgetter('score'),
    "latitude":attrgetter('loc.lat'),
    "longitude":attrgetter('loc.lon'),
    }

def getdict(obj):
    return dict(((k,v(obj)) for (k,v) in GETTER_MAP.items()))

if __name__ == "__main__":
    db_objs    = SQL("query")
    top_scores = [getdict(obj) for obj in db_objs]
    print top_scores
于 2013-08-17T08:27:08.513 回答
1

试试这个:

top_scores = [{"name":obj.name,
               "score":obj.score,
               "latitude": obj.loc.lat if hasattr(obj.loc, lat) else 0
               "longitude":obj.loc.lon if hasattr(obj.loc, lon) else 0}
               for obj in db_objs]

或者,在您的查询中设置一个默认值。

于 2013-08-17T07:53:32.750 回答
1

它不漂亮,但getattr()应该可以工作:

top_scores = [
    {
        "name": obj.name,
        "score": obj.score,
        "latitude": getattr(getattr(obj, "loc", None), "lat", None),
        "longitude": getattr(getattr(obj, "loc", None), "lon", None),
    }
    for obj in db_objs
]

如果存在,这会将带有键的 dict 项设置"latitude"obj.loc.lat(等等);如果不存在(即使obj.loc不存在),它将被设置为None.

于 2013-08-17T08:00:39.350 回答