0

これは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

以下のプログラム出力では、出力の前は出力の後と同じであると常に期待しています。

プログラム出力:

['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.
4

4 に答える 4

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
于 2013-03-20T19:46:35.900 に答える
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']
于 2013-03-20T19:33:31.900 に答える
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              <---
     ...
于 2013-03-20T19:33:34.257 に答える
0

これはバグではありません。変数 aFlag は、値によって渡されるため、特定の関数呼び出しに対してのみローカルです。プログラムが 'Before for 1' を出力すると、aNode[2:] が空であるため (aNode にはその時点で 2 つの要素しかありません)、for ループには入りません。したがって、「After for」を出力することはありませんが、すぐに戻ります。

for ループ内ではなく、実際には for ループの後に print ステートメント 'After for' を配置すると、出力がより明確になります。その後、出力は一貫します。

print "Before for ", aFlag
for elem in aNode[2:]:    
    findversion(elem,aList,aFlag)
print "After for ", aFlag
于 2013-03-20T19:37:42.270 に答える