评论中的一个解决方案,建议使用字典行工厂,似乎非常接近你想要的。
在我看来,更接近(更容易编写)的namedtuple
. 为此,我曾经写过:
def namtupiter(c):
from collections import namedtuple
fields = tuple(i[0] for i in c.description)
Row = namedtuple('Row', fields)
# make Row a tuple and a "dict" (well, kind of...) at the same time.
# Don't lose tuple property, so only process strings and pass everything
# other to super().
Row.__getitem__ = lambda self, item: getattr(self, item) if isinstance(item, basestring) else super(Row, self).__getitem__(item)
for i in c:
try:
# try to access i as a dict
yield Row(*(i[f] for f in fields))
except TypeError:
# it is no dict -> try tuple
yield Row(*i)
class CursorNTRowsMixIn(object):
_fetch_type = 0 # tuples
def _do_get_result(self):
super(CursorNTRowsMixIn, self)._do_get_result()
# create a named tuple class
from collections import namedtuple
if self.description:
self.RowClass = namedtuple('Row', tuple(i[0] for i in self.description))
def _fetch_row(self, size=1):
rows = super(CursorNTRowsMixIn, self)._fetch_row(size)
# turn every row into a Row().
return tuple(self.RowClass(*i) for i in rows)
class NTCursor(CursorStoreResultMixIn, CursorNTRowsMixIn,
BaseCursor):
pass
class SSNTCursor(CursorUseResultMixIn, CursorNTRowsMixIn,
BaseCursor):
pass
使用namtupiter()
,您可以遍历包含结果集的游标并接收带有作为属性包含的 DB 字段的 NamedTuples。
所以你可以做
for r in namtupiter(db.select(fields=('id', 'name', 'area', _from='sometable', where='area IS NOT NULL')):
print r.id, r.name, r.area
另一种方式是 ( SS
) NTCursor
,它可以被视为提供元组或字典的现有游标的替代方案。这些新游标还将行作为命名元组提供从结果集中提取的名称信息。