简体   繁体   English

如何在python“递归”函数中重置全局变量?

[英]How to reset a global variable in python “recursive” function?

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

I have this function which recursively iterated over a valid json.The json might contain dict or list.The function here searched takes some input log which is json and a key to search in the json.I am able to iterate to get all the keys in the json .Things are fine. 我有一个在有效json上递归迭代的函数。json可能包含dict或list。在这里搜索的函数需要一些输入日志,即json和搜索json的键。我能够迭代来获取所有键在json中。一切都很好。

But the problem comes when I try to return the value.Since the returnValue is a global variable .Appending to the list ,keeps on appending all the values to the same list.Even when I create an object of the class from some other module and call this function the list still grows and I am not able to clear/reset the returnValue before/after the function call.I need to change the returnValue which is a list each time the object is created from external module ie when the first time this function is called.So it is a problem where I need to return value with recursion. 但是问题出在我尝试返回值时。由于returnValue是全局变量。追加到列表后,继续将所有值追加到同一列表中。即使当我从其他模块创建类的对象时,调用此函数列表仍然会增长,并且我无法在函数调用之前/之后清除/重置returnValue。每次从外部模块创建对象时(即第一次执行此操作时),我都需要更改returnValue这是一个列表函数被调用,所以这是我需要递归返回值的问题。

Since the api is already defined I can only change the code within. 由于api已经定义,因此我只能在其中更改代码。

Please help. 请帮忙。 Thanks. 谢谢。

I think you should alter your recursive function to not need any global variables. 我认为您应该更改递归函数以不需要任何全局变量。 If you only expect to find a single result, I think it's not too complicated. 如果您只希望找到一个结果,那么我认为它并不太复杂。

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

If you might have multiple values in different dictionaries with the desired key, you'll probably need to pass a list around: 如果您在不同的字典中使用所需的键可能有多个值,则可能需要传递一个列表:

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
def getValueForSpecificKey(self,capturedLog,key,first=[])
global returnaValue
if not first:
   first.append(1)
   returnaValue = []

This will create a global empty list the first time you call it. 首次调用时,这将创建一个全局空列表。 This will indicate you should clear the global list, returnValue. 这将指示您应清除全局列表returnValue。 No api change and works with recursion 无需更改API即可使用递归

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

I have two functions in a class .I create the object of getValureForSpecificKey and pass a json and a key to search in it.I expect the value for this specific key.But what is the keys being appended incrementally to the same list even when the objects are different.I am not sure if the previous object is not getting destroyed ? 我在一个类中有两个函数。我创建了getValureForSpecificKey的对象,并传递了一个json和一个要在其中搜索的键。我希望这个特定键的值是什么?对象是不同的。我不确定先前的对象是否没有销毁? which is of least possibility since each object is in different function and has local scope. 这是最小的可能性,因为每个对象的功能不同且具有局部范围。

What am I missing here to make each call to the function separate from the previous call? 我在这里缺少什么使每次调用该函数都与上次调用分开?

So ,I want to know basically what is going wrong here in this solution? 因此,我想基本了解此解决方案在这里出了什么问题?

When I print the value for first only the first time the object is created the value is printed as 0 even if I create new object next time I get the same as 1 for the first call and not zero .Why is it happening ? 当我仅第一次创建对象时第一次打印该值时,即使我下次创建新对象时,该值也打印为0,但第一次调用时该值与1相同,而不是零。为什么会这样?

Okay , Here is the solution 好的,这是解决方案

Default parameter values are evaluated when the function definition is executed. 执行功能定义时,将评估默认参数值。 This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call. 这意味着在定义函数时,表达式将被计算一次,并且每个调用使用相同的“预先计算”值。 This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (eg by appending an item to a list), the default value is in effect modified. 这对于理解默认参数何时是可变对象(例如列表或字典)尤其重要:如果函数修改了该对象(例如,通过将项目附加到列表),则默认值实际上已被修改。 This is generally not what was intended. 这通常不是预期的。 A way around this is to use None as the default, and explicitly test for it in the body of the function, eg: 解决此问题的一种方法是使用None作为默认值,并在函数主体中显式测试它,例如:

def getValueForSpecificKey(self,capturedLog,key,First=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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM