2013-03-20 23 views
0

這是一個python的bug嗎?變量在循環遞歸函數中失去值。 這是測試代碼。我真的解析XML。python變量在recusive函數循環後失去值

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 for輸出與after for輸出相同。

程序輸出

['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版本

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. 

回答

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'] 
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    <--- 
    ... 
0

這不是一個錯誤。變量aFlag僅對特定函數調用是本地的,因爲它是按值傳遞的。當程序打印'Before for 1'時,它永遠不會進入for循環,因爲aNode [2:]是空的(aNode當時只有兩個元素)。因此,它不會打印任何'After for',但會立即返回。

如果您將print語句'After for'實際放在for循環之後而不是for循環中,輸出將會更清晰。那麼輸出將是一致的。

print "Before for ", aFlag 
for elem in aNode[2:]:  
    findversion(elem,aList,aFlag) 
print "After for ", aFlag 
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 
    for elem in aNode[2:]: 
     print "After for ", aFlag 
     aFlag = findversion(elem,aList,aFlag) 
    return aFlag