2011-12-13 25 views
1

私はPython 3関数(非ローカル変数を使用)を複数の関数内で使用する方法を理解しています。ここで私が言いたいのは非常に簡単な例です:Pythonの内部関数の再利用

def inner(airplane): 
    nonlocal var 
    if airplane == "Alpha": 
     var = a 
    elif airplane == "Beta": 
     var = b 
def outer1(airplane): 
    inner(airplane) 
    do stuff with var 
def outer2(airplane) 
    inner(airplane) 
    do other stuff with var 

outer1("FirstAirplane") 
outer2("SecondAirplane") 

私は(SyntaxError: No binding for nonlocal 'var' found)エラーを取得していますが、私は、私は非常に間違ってこれをやっている疑いがあります。私は今までにinner()を実行するつもりはありません。 inner()を正しい方法で再利用するにはどうすればよいですか?私はそれをouter1()の中に定義してから、outer2()に再利用できますか?

さて、ええと...好評...ここに私のコードの関連セクションだ...

def planeandoffset(airplane): 
    if airplane == "Zulu": 
     linename = "\\[\\INOV" 
     charoffset = 14 
    elif airplane == "Lima": 
     linename = "\\[\\ILIM" 
     charoffset = 10 
    elif airplane == "Mike": 
     linename = "\\[\\IMIK" 
     charoffset = 10 
    else: 
     print("There is no airplane by that name.") 
    latstart = charoffset 
    latend = 7 + charoffset 
    lonstart = 9 + charoffset 
    lonend = 17 + charoffset 
    return airplane, linename, latstart, latend, lonstart, lonend 

def latlongen(workingline, latstart, latend, lonstart, lonend): 
# Determine Latitude and Longitude in decimal format 
    latraw = workingline[latstart:latend] 
    if latraw[0:1] == "S": 
     pm = "-" 
    else: 
     pm = "" 
    hours = float(latraw[3:5] + "." + latraw[5:]) 
    decimal = hours/60 
    latitude = float(latraw[1:3]) + decimal 
    latitude = float(pm + str(latitude)) 
    lonraw = workingline[lonstart:lonend] 
    if lonraw[0:1] == "W": 
     pm = "-" 
    else: 
     pm = "" 
    hours = float(lonraw[4:6] + "." + lonraw[6:]) 
    decimal = hours/60 
    longitude = float(lonraw[1:4]) + decimal 
    longitude = float(pm + str(longitude)) 
    return latitude, longitude 
def kmlplanegen(airplane): 
    planeandoffset(airplane) 
    global afffilename, iconurl, kmlwrite 
    affread = open(afffilename) 
    while True: 
     line = affread.readline() 
     # Choose appropriate line 
     if line.startswith(linename): 
      workingline = line 
     elif len(line) == 0: # Zero length indicates EOF (Always) 
      break 
     else: 
      pass 
    try: 
     latlongen(workingline, latstart, latend, lonstart, lonend) 
    # Generate kml for Airplane 
     print(''' <Placemark> 
      <Style> 
       <IconStyle> 
        <Icon> 
         <href>{0}</href> 
        </Icon> 
       </IconStyle> 
      </Style> 
      <name>{1}</name> 
      <description>Latitude: {2} Longitude: {3}</description> 
      <Point> 
       <coordinates>{3},{2},0</coordinates> 
      </Point> 
     </Placemark>'''.format(iconurl,airplane,latitude,longitude), file=kmlwrite) 
    except Exception: 
     exit(1, "There was an error. This message is kind of worthless. Stopping Program") 

def kmlpathgen(airplane): 
    planeandoffset(airplane) 
    global afffilename, kmlwrite 
    # Generate kml for Airplane Path 
    print(''' <Style id="yellowLineGreenPoly"> 
     <LineStyle> 
      <color>7f00ffff</color> 
      <width>4</width> 
     </LineStyle> 
     <PolyStyle> 
      <color>7f00ff00</color> 
     </PolyStyle> 
    </Style> 
    <Placemark> 
     <name>{0} Path</name> 
     <description>Transparent green wall with yellow outlines</description> 
     <styleUrl>#yellowLineGreenPoly</styleUrl> 
     <LineString> 
      <extrude>1</extrude> 
      <tessellate>1</tessellate> 
      <altitudeMode>relativeToGround</altitudeMode> 
      <coordinates>'''.format(airplane), file=kmlwrite) 
    try: 
     affread = open(afffilename) 
     while True: 
      line = affread.readline() 
      if len(line) == 0: # Zero length indicates EOF (Always) 
       break 
      elif line.startswith(linename): 
       workingline = line 
       latlongen(workingline, latstart, latend, lonstart, lonend) 
       print("     {0},{1},0".format(longitude,latitude), file=kmlwrite) 
      else: 
       pass 
    except NameError: 
     pass 
    finally: 
     print('''   </coordinates> 
      </LineString> 
     </Placemark>''', file=kmlwrite) 
+0

あなたにはクラスが必要です:)チェックアウト:http://docs.python.org/tutorial/classes.html – Crisfole

+0

[非ローカルなものの説明](http://stackoverflow.com/a/) 1261961/832391)。 –

+1

短い答えは動的スコープを要求していますが、Python(「非ローカル」の有無にかかわらず)はレキシカルスコープしか提供していません。 – delnan

答えて

3

あなただけのプログラムを学んでいますか?

地域以外のものは忘れてしまいます。これを行うには正しい方法return varvarを返し、その後、呼び出し元のコンテキストでその結果を割り当てることです:

var = inner(airplane) 

編集:

planeandoffset(airplane) 

あなたは、単に呼び出している

返された値で何もしていません。それらにアクセスするには:

airplane, linename, latstart, latend, lonstart, lonend = planeandoffset(airplane) 

私はあなたがそれらのグローバルでやっていることを分析するつもりはありませんが、それは何でも、停止します。それらを関数間のパラメータとして渡すか、それらを関数とともにクラスに入れ、それらをクラスのメンバーとしてアクセスします。

いずれにしても、グローバルを使用しないより一般的なプログラミングスタイルを学ぶためのチュートリアルに従うことをお勧めします。

+1

残念ながら、いいえ、私は学ぶだけではありませんが、うまく再学習しようとしています。非常に機能的で、非常に醜いコードを書いています。それは維持するのは難しいことです。私は、できるだけ素早く共同作業を行うコードだけでなく、コードを書くことを学ぶ必要があると判断しました。 – Russianspi

+0

+1。グローバルと非ローカルについて忘れてください。リターンを使用します。それを簡単に。 –

+0

はい、それは理にかなっているようです。私は変数を "var"と呼ぶか、 "inner.var"のようなものを必要としますか?それはまだかなり正しく動作していません。 "Outer"はグローバル変数varを探していて、それを見つけることはできません。 – Russianspi

関連する問題