簡體   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