2016-11-04 5 views
0

Я продолжаю получать эту ошибку «RuntimeError: превышена глубина рекурсии при вызове объекта Python», когда я пытаюсь запустить мою хост-программу для инструмента тестирования смарт-карт с 600 тестами, и я получаю эту ошибку после 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(), я передаю это процессуResponse (resp), чтобы проанализировать, что следующий шаг должен отправлять и получать, и я передаю полученное сообщение процессуResponse каждый раз, и я считаю, что это то, что вызывает ошибку, поэтому мне нужно как-то прервать это так, чтобы я не продолжал называть processResponse (resp) ... – Mahs

+0

Хорошо. Основной принцип все тот же: верхний цикл перемещается от одного теста к другому. У вас может быть подпрограмма, анализирующая ответ, но передайте эту информацию обратно в верхний цикл для следующей итерации. – Prune

Смежные вопросы