2017-04-27 2 views
0

Ich schreibe ein kleines Stück Code, der Latex-Dateien analysiert und mir die neuen Befehle definiert. Ein Testfall wäre diese einfache Latex-Datei:Scope in Python in verschachtelten if-Anweisungen

% +--------------------------------------------------------------------+ 
% |                 | 
% | New particle stuff            | 
% |                 | 
% +--------------------------------------------------------------------+ 
\newcommand*{\Hmp}{\ensuremath{H^{\mp}}\xspace} 
\newcommand*{\susy}[1]{\ensuremath{\tilde{#1}}\xspace} 
\newcommand*{\susy2}[1,2]{\ensuremath{\tilde{#1}\tilde{#2}}\xspace} 

Es könnte ein komplizierter Fall sein, wenn der Befehl mehrere Zeilen erweitert, so brauche ich den Überblick über verschiedene Schritte zu halten, wie wenn der Befehl mit mehr Zeilen werden muss erhöht oder wenn der Befehl beendet ist und fertig ist.

Die Sache ist, dass innerhalb einiger verschachtelter if/else-Anweisungen der Gültigkeitsbereich der Variablen verloren geht und die Variablen nicht mehr aktualisiert werden. Hier ist, was bin ich tue:

macros = [] 
    warg_keep = re.compile("newcommand\*\{(.*)\}\[(.*)\]\{(.*)") 
    woarg_keep = re.compile("newcommand\*\{(.*)\}\{(.*)") 
    warg_one = re.compile("newcommand\*\{(.*)\}\[(.*)\]\{(.*)\}") 
    woarg_one = woarg = re.compile("newcommand\*\{(.*)\}\{(.*)\}") 
    keep = False 
    for line in open(file).readlines(): 
     line = line.strip() 
     if len(line) == 0 or line[0] == "%": 
      continue 
     if not keep: 
      newcommand = {"key":"","command":"","args":[]} 
     added = False 
     if "newcommand" in line: 
      if line[-1] == "%": 
       clean_line = line[0:-1] 
       keep = True 
       newcommand = get_cmd_from_line(warg_keep,woarg_keep,clean_line) 
      else: 
       newcommand = get_cmd_from_line(warg_one, woarg_one, line) 
       added = True 
     elif keep: 
      # Now it dos not matter how it ends, the command will always be added the line without the 
      # last character, it can be either % or } but it shouldn't be added 
      newcommand["command"] += line[0:-1] 
      # End the keep 
      if line[-1] != "%": 
       keep = False 
       added = True 
     elif added: 
      macros.append(newcommand) 

Das Problem ist, wenn ich die newcommand Variable den Wert zuweisen ich von der get_cmg_from_line Funktion erhalten (die ich getestet habe funktioniert perfekt) ist es nicht die newcommand Variable nicht aktualisiert, aber wenn Ich bewege es über das vorherige, wenn es es dann erkennt und aktualisiert. Das Gleiche passiert mit den keep- und addierten Variablen.

Ich habe gesucht und viele Dinge über Bereiche/if/Funktionen usw. gefunden, die ich schon kannte und wenn ich nicht Bereich definieren sollte ich nicht wissen, warum das passiert ... bin ich vermisst etwas Dummes? Wie sollte ich den Wert der newcommand-Variable aktualisieren? Da es mit neuen Zeilen aktualisiert werden könnte. Die einzige Lösung, die ich sehe, ist die Verflachung des Codes, aber ich würde es gerne so beibehalten.

EDIT: Ich habe ein wenig den ursprünglichen Code geändert, um zusätzliche Funktionen des Textes unterzubringen, aber ohne den Code zu verflachen, funktioniert es auch nicht. Der obige Code funktioniert also nicht aus dem von mir genannten Grund. Der folgende Code funktioniert perfekt und übergibt alle Tests:

macros = [] 
warg_keep = re.compile("newcommand\*\{(.*)\}\[(.*)\]\{(.*)") 
woarg_keep = re.compile("newcommand\*\{(.*)\}\{(.*)") 
warg_one = re.compile("newcommand\*\{(.*)\}\[(.*)\]\{(.*)\}") 
woarg_one = woarg = re.compile("newcommand\*\{(.*)\}\{(.*)\}") 
keep = False 
for line in open(file).readlines(): 
    line = line.strip() 
    if len(line) == 0 or line[0] == "%": 
     continue 
    if not keep: 
     newcommand = {"key":"","command":"","args":[]} 
    added = False 
    if "newcommand" in line and line [-1] == "%": 
     clean_line = line[0:-1] 
     keep = True 
     newcommand = get_cmd_from_line(warg_keep,woarg_keep,clean_line) 
    if "newcommand" in line and line[-1] != "%": 
     newcommand = get_cmd_from_line(warg_one, woarg_one, line) 
     added = True 
    if not "newcommand" in line and keep: 
     # Now it dos not matter how it ends, the command will always be added the line without the 
     # last character, it can be either % or } but it shouldn't be added 
     newcommand["command"] += line[0:-1]    
    if not "newcommand" in line and keep and line[-1] != "%": 
     # End the keep 
     keep = False 
     added = True 
    if added: 
     macros.append(newcommand) 

Antwort

0

Der Umfang der lokalen Variablen in Python (wie viele andere Skriptsprachen) ist auf Funktionsebene und nicht auf Blockebene.

Beispiel:

def function(): 
    x = 5 
    if True: 
     y = 8 
    print(x) 
    print(y) 

function() 
# -> 5 
# -> 8 
+0

Ja ich weiß, das ist es, ich erwarte, dass dies funktioniert, aber es scheint, dass innerhalb des zweiten Blocks die Variablen nicht erkannt werden. Sogar innerhalb von pycharm erscheinen sie ausgegraut, als würden sie nicht benutzt. –

3

Auf einer oberflächliche Prüfung, meine erste Vermutung ist, dass elif keep und elif added sollten if keep und if added betragen.

Eine weitere Möglichkeit besteht darin, dass Sie erwarten, dass sich der neue Befehl von einer Zeile zur nächsten anhäuft, Sie ihn jedoch bei jedem Durchlauf zurücksetzen. Soll newcommand = { … } vor die geschoben werden?

+0

Um den neuen Befehl zu bekommen, muss ich die Linie überprüfen. Ich habe den Code debuggen und es tut was es sollte in dem Sinne, dass es in die Blöcke geht und die Funktion aufgerufen wird und newcommand korrekt zugeordnet ist (!!) aber nach dem Ausgehen aus dem Block alle Variablen (newcommand, keep und added)) haben immer noch die alten Werte. –

+0

Was soll Ihr Skript tun, wenn 'keep' in der ersten' if-Zeile [-1] == "%" 'auf' True' gesetzt ist? Sollte es auch in 'elif keep' gehen oder nur in der nächsten Zeile? Weil das in Python nicht funktioniert, wie in der Antwort erwähnt. –

+0

Nein, wenn "keep" auf "true" gesetzt ist, sollte es nur für die nächsten Zeilen verwendet werden. Thre ist kein Fall, wenn "newcommand" in der Zeile steht und keep sollte auf "true" gesetzt werden. keep wird nur verwendet, um zu wissen, ob die nächsten Zeilen nach "newcommand" verwendet werden sollten, um die newcommand-Variablen zu inkrementieren.Als Mentioend, Debuggen des Codes Schritt für Schritt funktioniert es so, wie es sein sollte, die Variablen Zuweisungen werden Note außerhalb des zweiten Blocks gehalten. Wenn ich sie zu einer anderen Stelle bringe oder den Code abflache, dann funktioniert es ... das deutet darauf hin, dass ich nichts über den Umfang in Blöcken verrate. –