2016-11-04 105 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

相关问题