递归函数中的for循环后,Python变量失去了价值

0 人关注

这是一个Python bug吗?变量在递归函数的for循环后丢失了值。这是测试代码。我真的在解析XML。

def findversion(aNode, aList, aFlag):
    print "FindVersion ", aNode[0:1]
    print "Findversion ", aFlag
    if aNode[1].find('Software') != -1:
        aFlag = 1
        aList.append(aNode[1])
    if aFlag == 1 and aNode[0] == 'b':
        aList.append(aNode[1])
    print "Before for ", aFlag
    for elem in aNode[2:]:
        print "After for ", aFlag
        findversion(elem,aList,aFlag)
node = ['td', 'Software version']
node2 = ['b', '1.2.3.4' ]
node3 = [ 'td', ' ', node2 ]
node4 = [ 'tr', ' ', node, node3 ]
print node4
myList = list()
myInt = 0
findversion(node4,myList,myInt)
print "Main ",myList

在下面的程序输出中,我总是希望输出前和输出后是相同的。

程序输出。

['tr', ' ', ['td', 'Software version'], ['td', ' ', ['b', '1.2.3.4']]]
FindVersion  ['tr']
Findversion  0
Before for  0
After for  0
FindVersion  ['td']
Findversion  0
Before for  1
After for  0
FindVersion  ['td']
Findversion  0
Before for  0
After for  0
FindVersion  ['b']
Findversion  0
Before for  0
Main  ['Software version']

Python version:

Python 2.7.3 (default, Dec 18 2012, 13:50:09)
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
    
python
recursion
Robert Jacobs
Robert Jacobs
发布于 2013-03-21
4 个回答
Andrew Clark
Andrew Clark
发布于 2013-03-21
已采纳
0 人赞同

混乱的输出是因为 After for 0 的输出来自函数的不同递归调用(与刚才的 Before for 0 的输出不是同一个)。

这里是你的函数的一个版本,有一些额外的信息来跟踪递归调用的深度。

def findversion(aNode, aList, aFlag, i=1):
    print "FindVersion ", aNode[0:1], 'call:', i
    print "Findversion ", aFlag, 'call:', i
    if aNode[1].find('Software') != -1:
        aFlag = 1
        aList.append(aNode[1])
    if aFlag == 1 and aNode[0] == 'b':
        aList.append(aNode[1])
    print "Before for ", aFlag, 'call:', i
    for elem in aNode[2:]:
        print "After for ", aFlag, 'call:', i
        findversion(elem,aList,aFlag,i+1)

这里是新的输出,显示了我正在谈论的内容。

FindVersion  ['tr'] call: 1
Findversion  0 call: 1
Before for  0 call: 1
After for  0 call: 1
FindVersion  ['td'] call: 2
Findversion  0 call: 2
Before for  1 call: 2         # this is from the recursive call
After for  0 call: 1          # this is from the original call
FindVersion  ['td'] call: 2
Findversion  0 call: 2
Before for  0 call: 2
After for  0 call: 2
FindVersion  ['b'] call: 3
Findversion  0 call: 3
Before for  0 call: 3
Main  ['Software version']
    
Pavel Anossov
Pavel Anossov
发布于 2013-03-21
0 人赞同

这个 After 是来自封闭的 findversion 调用。

print Before for 0 start iterating over aNode first td: print After for 0 call findversion print FindVersion ['td'] print Findversion 0 find Software, set aFlag = 1 print Before for 1 <--- start iterating over aNode it's empty second td: print After for 0 <---
fvannee
fvannee
发布于 2013-03-21
0 人赞同

这不是一个错误。变量aFlag只是特定函数调用的局部,因为它是通过值传递的。当你的程序打印'Before for 1'时,它从未进入for循环,因为aNode[2:]是空的(aNode在那时只有两个元素)。因此,它从不打印任何'After for',而是立即返回。

如果你把打印语句'After for'真正放在for循环之后,而不是放在for循环里面,输出会更清晰。那么输出就会一致。

print "Before for ", aFlag
for elem in aNode[2:]:    
    findversion(elem,aList,aFlag)
print "After for ", aFlag
    
Robert Jacobs
Robert Jacobs
发布于 2013-03-21
0 人赞同

所以为了修复我的程序,我需要返回这个标志。

def findversion(aNode, aList, aFlag):
    print "FindVersion ", aNode[0:1]
    print "Findversion ", aFlag
    if aNode[1].find('Software') != -1:
        aFlag = 1
        aList.append(aNode[1])
    if aFlag == 1 and aNode[0] == 'b':
        aList.append(aNode[1])
        aFlag = 0
    print "Before for ", aFlag