2012-10-11 3 views
1

collection.find() 메소드가 기본에서 상속하는 사용자 정의 커서 클래스를 반환하지만 iteration이 발생하는 방법을 재정의 할 수 있습니까?pymongo - 사용자 정의 커서 클래스 사용

커서 내의 몽고 데이터에서 특정 모델을 반복적으로 인스턴스화하고 싶습니다. 문서에는 어떤 종류의 인스턴스를 만들어야할지 결정하는 type attr이 있습니다. next 메서드가이 데이터를보고 생성하고 반환 할 유형을 결정할 수 있다고 생각했습니다. 커서를 상속하는 것은 쉽지만, find() 작업에 연결할 위치를 파악할 수 없습니까?

편집는 또한 ...

는 내가 현재하고 있어요하여 수행 될 때 가져 사후 객체를 분류하는 발전기를 뱉어 yield을 사용하는 것입니다.

@classmethod 
def gather(cls,place_id): 
    """ 
    Gather instances of all the shouts for one place 
    """ 
    shouts = cls.collection.find({'place_id':place_id}) 
    for s in shouts: 
     yield Shout.classify(s) 

@classmethod 
def classify(cls,shout): 
    if shout.type == 1: 
     return Type1(dict(shout)) 
    elif shout.type == 2: 
     return Type2(dict(shout)) 
    elif shout.type == 3: 
     return Type3(dict(shout)) 

문제는이 Cursor pymongo 기본에 캡슐화되어 키 액세스를 브래킷에 원래의 접근 방식을 유지하지 않습니다.

커서 인스턴스를 받아들이고 메서드를 래핑하는 래퍼 클래스를 만들려면 원래의 커서의 반복 동작을 유지하기 위해 어떤 마법 메서드를 재정의해야합니까? 나는 이런 식으로 뭔가를 생각하고 있어요 : 이것은 내가 생각할 수있는 것입니다 만,

class StuffCursor(): 

    cursor = False 

    def __init__(self,cursor): 
     self.cursor = cursor 

    def __getattr__(self,attr): 
     #This passes off most key-based calls, like bracket-access, to the cursor 
     return getattr(self.cursor,attr) 

, 수정 된 반복자를 반환 한 후 반복자의 상단에 약간의 추가 처리를 스택, 그리고 것 아무것도 작동합니다.

답변

1

내 자신의 질문에 싫어할 지 모르지만, 이는 인터넷 검색 사용자에게 유용 할 수 있습니다. 여기에 내가 함께가는 결국 내용은 다음과 같습니다 발전기가 반환로 수정, 인스턴스화 모델은 최대로드되는 곳

class ShoutCursor(): 
    """ 
    Custom cursor class that will instantiate shout models 
    at query time. 
    """ 

    cursor = False 

    def __init__(self,cursor): 
     self.cursor = cursor 
     self.cursor.sort('created',DESCENDING) 

    def __iter__(self): 
     for ent in self.cursor: 
      yield Shout.classify(ent) 

    def __len__(self): 
     return self.cursor.count() 

    def __getitem__(self,index): 
     try: 
      ents = itertools.islice(self.cursor,index,index+1) 
      return [Shout.classify(ent) for ent in ents][0] 
     except TypeError: 
      return list(Shout.classify(ent) for ent in itertools.islice(self.cursor,index.start,index.stop,index.step)) 

    def sort(*args,**kwargs): 
     self.cursor.sort(*args,**kwargs) 

    def __getattr__(self,attr): 
     return getattr(self.cursor,attr) 

__iter____getiem__ 방법이 있습니다. 다른 메서드는 네이티브 커서 동작을 유지합니다. __init__에 커서를 전달하면 기능이 설정되므로 mongo에서 객체를 가져올 때 반복 논리마다 특수한 수행이 가능합니다.

관련 문제