繁体   English   中英

用于数据转换的Python设计模式

[英]Python Design Pattern for data transformations

我发现自己做了很多这样的事情:

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
    }

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

有没有使这些类型的转换更易于编码的设计模式或其他开发人员友好的方法?

我曾考虑过创建一个表和相关函数来转换简单的属性名称,但是我感觉在处理更复杂的数据转换时效果不佳。 而且,从长远来看,该方法可能不会为我节省很多工作。

有什么建议么?

您至少可以使用地图清除if 当我有大量转换时,我喜欢这样做。

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 ,则可以在运行时轻松地添加或覆盖转换。

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

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'}

我现在建议的唯一一件事就是至少在一个地方进行此转换。 因此,也许定义一个“要查询的垃圾”功能(最终还是要反向吗?),该功能在一个地方包含所有这些转换。 然后在需要进行此类转换的地方使用该函数。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM