[英]Python variable loses value after for loop in recursive function
这是一个Python错误吗? 变量在递归函数中的 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
在下面的程序输出中,我总是希望 Before 输出与 After 输出相同。
程序输出:
['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 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.
令人困惑的输出是因为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']
这个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 <---
...
这不是一个错误。 变量 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
所以为了修复我的程序,我需要返回标志。
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
for elem in aNode[2:]:
print "After for ", aFlag
aFlag = findversion(elem,aList,aFlag)
return aFlag
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.