2013-05-13 7 views
1

나는 나 자신이 같은 꽤 무언가를 찾을 변환 : 파이썬 디자인 패턴은

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 
    } 

이 구현 세부 사항을 무시합니다. 여기서 핵심은 비슷한 데이터를 공유하고 단순하고 반복적이며 복잡한 변환을 수행하는 두 개의 데이터 구조를 다루고 있다는 것입니다.

이러한 유형의 변환을 쉽게 코드화 할 수있는 디자인 패턴이나 다른 개발자 친화적 인 방법이 있습니까?

간단한 속성 이름을 변환하기 위해 테이블과 관련 함수를 만들려고 생각했지만 좀 더 복잡한 데이터 변환을 다룰 때 잘 돌아 가지 않을 것이라는 느낌이 들었습니다. 또한, 그 방법은 장기적으로 나에게 많은 작업을 절약하지 못할 수도 있습니다.

제안 사항?

+0

당신은 MongoDB를 작업하고 쿼리? –

+0

예. 몽고와 함께하는 것이 더 쉬운 방법이 있다면, 그것에 대해 듣고 싶습니다. 그러나 MongoDB (또는 그 문제에 대한 DB)와 완전히 관련없는 전에 이런 종류의 문제에 부딪혔을 때 나는 정말로 '일반적인'답을 찾고있다. – Kurtis

+2

어쩌면 그것은 내 자신의 nitpick이지만 키가 존재하는지 검사하는 것을 싫어한다. 그것을 액세스하기 전에. 간단히'try : ... except KeyError : pass'를 사용합니다. 정말 자주 사용하는 경우 컨텍스트 관리자를 만들고'SuppressKeyError() : ... '와 같은 것을 사용할 수 있습니다. – Bakuriu

답변

0

지금 당장 권장 할 수있는 유일한 방법은 최소한이 변환을 한 곳에서만 수행하는 것입니다. 그래서 "kwargs to query"함수 (결국 역으로?)를 정의하면 모든 변환이 단일 위치에 포함됩니다. 그리고 그런 전환을 할 필요가있을 때마다이 기능을 사용하십시오.

단일 값을 변환하는보다 일반적인 방법을 만들 수도 있지만 여러 번 호출해야 할 수도 있습니다. 그 일반적인 변환 방법에 많은 특수한 경우를 추가해야 할 것입니다. 대신 전체 구조에 대한 변환을 유지하십시오.

1

지도를 사용하여 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 클래스 또는 인스턴스 속성을 경우에도 쉽게 추가 할 수 있습니다 또는 당신이 원하는 경우 런타임에 변환을 덮어 씁니다.

1

당신은 클래스의 변환을 캡슐화하는 것이 좋습니다 :

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

나는 이것을 정말로 좋아한다. 이 기능을 여러 장소 (Django보기, API 코드 및 사용자 정의 Mongo 모델)에서 사용하는 좋은 방법입니다. 나는 그것을 시험해보고 그것이 얼마나 유연하고 재사용 가능한지를 볼 것입니다. 나는 모든 사람들에게 제안을 한 후에 대답을 '수락'할 것입니다. 감사! – Kurtis

관련 문제