2017-01-25 3 views
0

[EDITED]Python Rekursion Parameter ändern NUR innerhalb wenn

Ich bin eine wirklich seltsame Fehler mit und ich kann nicht ganz meinen Kopf wickeln um ihn herum. Wie ist es möglich, dass ID immer noch 1 ist (es wird initialisiert auf 1, wenn die Rekursion beginnt) innerhalb der for-Anweisung.

def recursive_read(root, id, cursor, database): 
     if root.text is not None: 
      cursor.callproc('add_node', (id, root.text)) 
      database.commit() 
      #print('Adding element to db... ') 
      id = id+1 
     for elem in root.getchildren(): 
      recursive_read(elem, id, cursor, database) 

EDIT:

Dies bildet einen perfekten Baum, aber es ist unglücklicherweise nicht, was ich will. Ich möchte diese Einrückung "verschieben", so dass Kind korrekt auf Eltern verweisen kann, und dafür muss ich ID nur erhöhen, wenn Element mit Text angetroffen wird, so bleibt das Problem bestehen.

def recursive_read(root, indent): 
    if root.text is not None: 
     print(' '*indent + '%s' % (root.text)) 
    for elem in root.getchildren(): 
     recursive_read(elem, indent+1) 

Was sollte ich ändern, damit sich die ID ändert NUR WENN root.text nicht None?

+0

Der von Ihnen bereitgestellte Code ändert nur den Wert von id, wenn 'root.text nicht None' ist. Wenn das nicht passiert, dann ist dieses Code-Snippet nicht der Fehler. – Olian04

+1

Erwarten Sie, dass ID nach dem rekursiven Aufruf geändert wird? Als Parameter übergebene Integer sind unveränderlich und werden daher im Aufrufer nicht geändert. Sie sollten 'return id' und' id = recursive_read (elem, id, cursor, database) '. – cdarke

+0

Ich wollte ID erhöhen, wenn Text nicht None ist und wenn es nicht ist, sollte es wie der angegebene Wert bleiben – xxxxx

Antwort

0

Das Problem ist, dass ID ist ein Parameter an die rekursive Funktion übergeben, keine globale Variable. Was sich bei einem Anruf in ID ändert, betrifft nur nachfolgende Anrufe, die von diesem Anruf paraphiert wurden, und keine Anrufe, die von anderen Anrufen initiiert wurden. Nehmen wir zum Beispiel an, auf Ebene eins, wenn ID vor der for-Schleife einen Wert von 2 hat, dann wird jede Iteration der Schleife 2 als den Wert von id zu recursive_read() übergeben. Unabhängig davon, wie viele Ebenen die aufgerufene rekursive_read() abstürzt und die id mehrmals ändert, bleibt die id immer noch 2, und beim nächsten Aufruf von recursive_read() in der Schleife wird immer noch id mit dem Wert 2 übergeben.

+0

Vorsicht mit globas, sie [sind böse] http://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil Rückgabe der aktuelle Wert der ID scheint eine viel bessere Ansatz als @ cdarke schlug in den Kommentaren vor –