2016-11-04 103 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,並且我相信這是導致錯誤的原因,所以我需要以某種方式折射這種方式,以便我不會一直調用processResponse(resp)... – Mahs

+0

精細。基本原理仍然是一樣的:上一個循環從一個測試移動到另一個測試。您可能有一個子程序分析響應,但將該信息傳回上一個循環以進行下一次迭代。 – Prune

相關問題