如何在python中重置全局变量"递归"功能?

时间:2015-02-21 19:43:47

标签: python json recursion

def getValueForSpecificKey(self,capturedLog,key):

     ''' Get value from log for any specific key,caputredLog must be a string'''
     global Found
     global returnValue
     if type(capturedLog)==type({}):
         for eachKey in capturedLog:
             if eachKey==key:
                 Found=True
                 print "Found Key Match :",eachKey
                 print capturedLog[key]
                 listAppendValue=capturedLog[key]
                 #returnValue=capturedLog[key]
                 returnValue.append(listAppendValue)
                 print "="*1000
                 print "The value for key in the captured Log is -> ",capturedLog[key]
                 print " Return value "*10,(returnValue)
                 return Found,returnValue
             self.getValueForSpecificKey(capturedLog[eachKey],key)
     elif type(capturedLog) is list:
         for elements in capturedLog:
             self.getValueForSpecificKey(elements,key)
     print returnValue
     return Found,returnValue

我有这个函数,它递归迭代一个有效的json.json可能包含dict或list。这里搜索的函数需要一些输入日志,它是json和一个在json中搜索的键。我能够迭代得到json中的所有键。这些都很好。

但是当我尝试返回值时出现了问题。因为returnValue是一个全局变量。继续列表,继续将所有值附加到同一个列表。即使我从某些创建类的对象其他模块并调用此函数列表仍然增长,我无法在函数调用之前/之后清除/重置returnValue。我需要更改returnValue,这是每次从外部模块创建对象时的列表,即第一次调用这个函数。所以我需要通过递归返回值。

由于api已经定义,我只能更改其中的代码。

请帮忙。 感谢。

4 个答案:

答案 0 :(得分:1)

我认为你应该改变你的递归函数,不需要任何全局变量。如果您只希望找到一个结果,我认为它并不太复杂。

def getValueForSpecificKey(self, capturedLog, key):
    '''
    Get value from log for any specific key.
    capturedLog will be searched if it is a list or dictionary.
    Returns None if the key is not found, or capturedLog is another type.
    '''

    if isinstance(capturedLog, dict):
        if key in capturedLog:                # base case #1 (found the key)
            return capturedLog[key]

        values = capturedLog.values()

    elif isinstance(capturedLog, list):
        values = capturedLog

    else:
        return None                           # base case #2 (not a list or dict)

    for value in values:
        result = self.getValueForSpecificKey(value, key)      # recursive case
        if result is not None:
            return result

    return None                               # nothing found in the recursive search

如果您在具有所需键的不同词典中有多个值,则可能需要传递一个列表:

def getValueForSpecificKey(self, capturedLog, key, results=None):
    '''
    Get value from log for any specific key.
    capturedLog will be searched if it is a list or dictionary.
    Returns an empty list if the key is not found, or capturedLog is another type.
    '''
    if results is None:
        results = []               # start a new list if this is a non-recursive call

    if isinstance(capturedLog, dict):
        if key in capturedLog:
            results.append(capturedLog[key])     # found a result, add it to the list
            return results

        values = capturedLog.values()

    elif isinstance(capturedLog, list):
        values = capturedLog

    else:
        return results

    for value in values:  # recursive calls will add to the results list as necessary
        self.getValueForSpecificKey(value, key, results)

    return results

答案 1 :(得分:0)

def getValueForSpecificKey(self,capturedLog,key,first=[])
global returnaValue
if not first:
   first.append(1)
   returnaValue = []

这将在您第一次调用它时创建一个全局空列表。这将表明您应该清除全局列表returnValue。没有api更改并且适用于递归

答案 2 :(得分:0)

def __init__(self):
    self.Found=False
    self.returnValue=[]

def getValueForSpecificKey(self,capturedLog,key,first=[]):
    ''' Get value from requests log for any specific key,caputredLog must be a string'''
     global Found
     global returnValue
     print " FIRST --------------------------->>>>>>",first
     if not first:
         print "NOT FIRST"*1000
         time.sleep(3)
         first.append(1)
         Found=False
         returnValue=[]
     if type(capturedLog)==type({}):
         for eachKey in capturedLog:
             if eachKey==key:
                 Found=True
                 print "Found Key Match :",eachKey
                 print capturedLog[key]
                 listAppendValue=capturedLog[key]
                 returnValue.append(listAppendValue)
                 print "="*1000
                 print "The value for key in the captured Log is -> ",capturedLog[key]
                 print " Return value "*10,(returnValue)
                 return Found,returnValue
             self.getValueForSpecificKey(capturedLog[eachKey],key)
     elif type(capturedLog) is list:
         for elements in capturedLog:
             self.getValueForSpecificKey(elements,key)
     return Found,returnValue

我在一个类中有两个函数。我创建了getValureForSpecificKey的对象并传递了一个json和一个键来搜索它。我期望这个特定键的值。但是这些键是以递增方式附加到同一个列表中的即使对象不同。我不确定前一个对象是否没有被破坏?这是最不可能的,因为每个对象具有不同的功能并具有局部范围。

我在这里缺少什么来使每次调用函数与前一次调用分开?

所以,我想知道这个解决方案中基本上出了什么问题?

当我第一次打印该值时,第一次创建对象时,即使我在下次第一次调用时得到1而不是零时创建新对象,该值也会打印为0。为什么会发生这种情况?

答案 3 :(得分:0)

好的,这是解决方案

执行函数定义时,将评估默认参数值。这意味着当定义函数时,表达式被计算一次,并且每次调用使用相同的“预先计算”值。这对于理解默认参数何时是可变对象(例如列表或字典)尤其重要:如果函数修改对象(例如,通过将项附加到列表),则默认值实际上被修改。这通常不是预期的。解决这个问题的方法是使用None作为默认值,并在函数体中显式测试它,例如:

def getValueForSpecificKey(self,capturedLog,key,First = None):

     ''' Get value from requests log for any specific key,caputredLog must be a string'''
     global Found
     global returnValue
     if First is None:
         First='notnone'
         Found=False
         returnValue=[]
         print "Return Value ->",returnValue
         print "Found - >",Found

     if type(capturedLog)==type({}):
         for eachKey in capturedLog:
             print eachKey
             if eachKey==key:
                 Found=True
                 print "Found Key Match :",eachKey
                 print capturedLog[key]
                 listAppendValue=capturedLog[key]
                 returnValue.append(listAppendValue)
                 print "="*1000
                 print "The value for key in the captured Log is -> ",capturedLog[key]
                 print " Return value "*10,(returnValue)
                 return Found,returnValue
             print "CapturedLog - >",capturedLog
             print "Calling using recursion "
             self.getValueForSpecificKey(capturedLog[eachKey],key,First)
     elif type(capturedLog) is list:
         for elements in capturedLog:
             self.getValueForSpecificKey(elements,key,First)
     return Found,returnValue