2016-11-04 4 views
0

600 개의 테스트를 가진 스마트 카드 테스트 도구에 대한 호스트 프로그램을 실행하려고하면 "RuntimeError : Python 객체를 호출하는 동안 최대 재귀 심도 초과"오류가 계속 발생하고이 오류가 발생합니다. 300 번째 테스트에서 "sys.setrecursionlimit (10000)"을 시도했는데 문제가 해결되었지만이 오류에 대한 최선의 방법이 아니라는 것을 알고 있습니다. 어떻게 코드를 변경하여이 문제를 해결할 수 있습니까? 오류 :runtimeerror : 최대 재귀 수준이 Python을 초과했습니다

def SndRcv(self,request): 
    print ">> ", request 
    device_api.send(request) 
    resp = device_api.receive() 
    print "<< ", resp 
    self.processResponse(resp) 

def processResponse(self, K400Message): 
    global mWaitingCardRemoval 
    ciMsg = card_interface_response 
    ciMsgType = card_interface_response.ci_msg 

    if ciMsgType is None: 
     print 'weird, malformed protobuf response' 
     return 
    whichMsg = ciMsgType.WhichOneof('msg') 
    print 'msg = ' + str(whichMsg) 
    if whichMsg is 'collision': 
     self.StartSession() 
    elif whichMsg is 'card_removed': 
     if ciMsgType.issuer== ci.CARD_INTERFACE_MASK_CxLESS:     
      mWaitingCardRemoval &= ~(ciMsgType.issuer) 
      if EndofSession is False: 
       self.parseMessage() 
      if mWaitingCardRemoval !=0: 
       self.parseMessage() 
      self.StartSession() 
    elif whichMsg is 'waiting_removal': 
     if EndofSession is False: 
      self.parseMessage() 
     else: 
      mWaitingCardRemoval |= ciMsgType.issuer 
    elif whichMsg is 'card_detected': 
     mode = ciMsgType.issuer 
     reqMsg = pm.get_Deactivate((ci.CARD_INTERFACE_MASK_ANY)& ~(ciMsgType.issuer)) 
     self.SendOnly(reqMsg) 
     acceptMsg = pm.get_Activate(mode) 
     self.SndRcv(acceptMsg) 
    elif whichMsg is 'card_ready': 
     self.StartLoop(ciMsgType.issuer) 
    elif whichMsg is 'rapdu': 
     self.processCardAPDUResponse(ciMsgType.issuer, ciMsg.data.encode('hex')) 
    elif whichMsg is 'card_not_responding': 
     if ciMsgType.issuer == ci.CARD_INTERFACE_MASK_CONTACT: 
      self.EndCardSession(ciMsgType.issuer,True) 
     else: 
      self.EndCardSession(ciMsgType.issuer, False) 
    elif whichMsg is 'resp_special': 
     if ciMsg.data.encode('hex') > 0: 
      logging.info(ciMsg.data.encode('hex')) 
     else: 
      logging.info("") 
+1

'self.SndRcv'는'self.processResponse'를 호출하고,'self.processResponse'는'self.SndRcv'를 호출합니다. 왜 이것이 임의의 심도 재귀를 야기하는지 알 수 있습니까? –

+0

재귀를 이해하려면 먼저 재귀를 이해해야합니다 ... – moooeeeep

+1

조금 확장 :'''SndRcv'''는 결코 반환되지 않고''processResponse'''는 ciMsgType이 None'''' 인 경우에만'''를 반환합니다. – wwii

답변

0

본질적으로 반복 프로세스를 코딩하는 데 재귀를 사용했습니다. 실제로 큰 문제를 작은 문제로 축소하는 것이 아닙니다. 당신은 일련의 입력을 거치고 있습니다. 입력을 처리하고 응답을보고하면 이 완료되어으로 처리됩니다. 호출 스택의 컨텍스트를 유지할 이유가 없습니다. 최종 테스트를 치고 천 이상의 전화를 통해 돌아 오면 결과 나 기능 상태로 아무 것도하지 않고 메인 프로그램으로 돌아갑니다.

간단한 반복으로 다시 작성하십시오. 어떻게 시작하니? 한 시험에서 다른 시험으로 어떻게 진행합니까? 당신이 언제 끝났는 지 어떻게 압니까?

# Get first response 
while ciMsgType is not None: 
    # Process this response 
    # Get next response 

합니까 당신이 이동 얻을 : 예를 들어, 당신의 가장 바깥 쪽 루프는 간단한 상태에 달려 것을 확실히 가능?

+0

시작 세션을 호출하는 방식으로 시작한다. 이 코드에는 여기에 포함되지 않았습니다. 기본적으로 SndRcv를 사용하여 세션을 시작하는 명령을 테스트 도구에 보내고 응답 형식에 따라 resp = device_api.receive()에서 얻은 결과를 processResponse (resp)로 전달하여 다음 단계를 분석해야합니다. 보내고받을 때마다받은 메시지를 processResponse에 전달할 때마다 오류가 발생한다고 믿습니다. 그래서 저는 어떻게해서든지 refractor를 사용하여 processResponse (resp)를 호출하지 않아야합니다 ... – Mahs

+0

벌금. 기본 원칙은 여전히 ​​동일합니다 : 상단 루프는 한 테스트에서 다음 테스트로 이동합니다. 서브 루틴이 응답을 분석 할 수 있지만 그 정보를 다음 반복을 위해 상위 루프로 다시 전달할 수 있습니다. – Prune

관련 문제