2

我发现自己经常做这样的事情:

if 'id' in kwargs:
    query['_id'] = ObjectID(kwargs.pop('id'))
if 'name' in kwargs:
    query['event'] = kwargs.pop('name')
if 'keywords' in kwargs:
    keywords = kwargs.pop('keywords')
    query['keywords'] = {
        '$in': keywords
    }

忽略实现细节。这里的要点是我正在处理两个共享相似数据并执行简单、重复和更复杂的转换的数据结构。

是否有任何设计模式或其他对开发人员友好的方法可以使这些类型的转换更易于编码?

我想过创建一个表和关联函数来转换简单的属性名称,但我感觉在处理更复杂的数据转换时效果不佳。此外,从长远来看,这种方法可能不会为我节省大量工作。

有什么建议么?

4

3 回答 3

2

您至少可以if用地图清除 s 。当我有一大群变换时,我喜欢这样做。

transforms = {'id' : ('_id', lambda val: ObjectID(val)),
              'name' : ('event', lambda val: val),
              'keywords' : ('keywords', lambda val: val)}
for kwargs_key in kwargs.keys():
    try:
        query_key, transform = transforms[kwargs_key]
    except KeyError:
        # Default or error handling
    else:
        query[query_key] = transform(kwargs.pop(kwargs_key))

如果您将其包装在一个类中并创建transforms一个类或实例属性,您甚至可以根据需要在运行时轻松添加或覆盖转换。

于 2013-05-13T20:05:02.473 回答
2

您可以考虑将转换封装在一个类中:

class QueryAdapter(object):
    def __init__(self, **kwargs):
        self.kwargs = kwargs
    def __getitem__(self, item):
        try:
            method = getattr(self, item)
        except AttributeError:
            raise IndexError(item)
        else:
            return method()
    def _id(self):
        return 'ObjectID({})'.format(self.kwargs['id'])
    def event(self):
        return self.kwargs['name']
    def keywords(self):
        return {'$in': self.kwargs['keywords']}

一旦定义了QueryAdapter,其余代码就变得非常简单:

kwargs = dict(id='abc', name='def')
query = QueryAdapter(**kwargs)

print(query['_id'])
# ObjectID(abc)
print(query['event'])
# def
print(query['keywords'])
# {'$in': 'key'}
于 2013-05-13T20:08:22.943 回答
0

我现在唯一推荐的就是至少在一个地方进行这种转换。所以也许可以定义一个“kwargs to query”函数(最终也是相反的?),在一个地方包含所有这些转换。然后在需要进行此类转换的任何地方使用该功能。

您可能能够创建一些更通用的方式来转换单个值,但您还需要多次调用它。更不用说您必须在该通用转换方法中添加许多特殊情况。因此,只需保留完整结构的转换即可。

于 2013-05-13T20:01:58.587 回答