2017-04-27 25 views
0

私はラテックスファイルを解析し、定義された新しいコマンドを私に与える小さなコードを書いています。テストケースは、この単純なLaTeXファイルのようになります。Pythonで入れ子にされたif文のスコープ

% +--------------------------------------------------------------------+ 
% |                 | 
% | 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} 

コマンドは、私は、コマンドが複数行にインクリメントする必要がある場合のように異なる工程を追跡する必要があるので、いくつかのラインを拡張し、より複雑なケースがあるかもしれませんまたはコマンドが終了して終了する準備が整ったときに実行されます。

ネストされたif/elseステートメントの中では、変数のスコープが失われているように見え、変数はもう更新されません。ここで私はやっていますものです:

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) 

問題私はnewcommand変数私は(私は完全に作品をテストしている)get_cmg_from_line関数から取得した値を代入するとき、それはnewcommand変数を更新していないですが、もしそれを認識して更新すれば、前のページに移動します。同じことが、保持変数と追加変数でも起こります。

私はこれを探して、私が知っていたスコープ/ if/functionsなどについて多くのことを発見しました。なぜなら、スコープを定義してはならない場合、なぜこれが起こっているのか分かりません...あほらしいもの? newcommand変数の値をどのように更新すればよいですか?新しいラインが登場すると更新されるかもしれないから。私が見る唯一の解決策は、コードを平坦化することですが、私はこれをこのように維持したいと思います。

EDIT:テキストの余分な機能に対応するために少し元のコードを変更しましたが、コードを平坦化せずにも機能しません。だから上のコードは私が言及した理由のために働いていない。以下のコードは完璧に動作し、すべてのテストに合格:

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) 

答えて

0

(多くの他のスクリプト言語のような)Pythonでローカル変数のスコープは、機能レベルではなく、ブロックレベルです。

例:一瞥で

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

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

はい、これはうまくいくと思いますが、2番目のブロック内で変数が認識されないようです。 pycharm内であっても、使用されていないように、グレー表示されます。 –

3

、私の最初の推測ではelif keepelif addedはそれぞれ、if keepif addedでなければならないことです。

もう1つの可能性は、newcommandがある行から次の行に累積することを期待していますが、それぞれのパスでその行をリセットすることです。 newcommand = { … }for line in …:の前に移動する必要がありますか?

+0

新しいコマンドを取得するには、行を検査する必要があります。私はコードをデバッグしていて、ブロックに入り、関数が呼び出され、newcommandが正しく関連付けられている(!!)が、ブロックから出てすべての変数(newcommand、keepおよびadded )はまだ古い値を持っています。 –

+0

最初の 'if line [-1] =="% "'で 'keep'が' True'に設定されているときのあなたのスクリプトは何ですか?それは 'elif keep 'の中に行かなければならないのでしょうか、それとも次の行だけにするのでしょうか?それは、答えで述べたように、Pythonではうまくいきません。 –

+0

いいえ、keepがtrueに設定されている場合は、次の行にのみ使用し、 "newcommand"が行内にあり、keepをtrueに設定する必要はありません。 keepは、newcommand変数の値をインクリメントするために "newcommand"の後の次の行が使用されるべきかどうかを知るためにのみ使用されます。mentioendとして、コードをステップバイステップでデバッグすると、変数の割り当てが2番目のブロックの外側に保持されている必要があります。私がそれらを1つのabouveに移動したり、コードを平坦化すれば、それは機能します...これは、私がブロック内のスコープについて何かを理解していないと指摘しています。 –

関連する問題