Повторное использование внутренней функции в Python - PullRequest
1 голос
/ 14 декабря 2011

Я пытаюсь выяснить, как использовать функцию Python 3 (используя нелокальные переменные) в более чем одной другой функции, не определяя ее заново.Вот очень упрощенный пример того, что я имею в виду:

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)

1 Ответ

3 голосов
/ 14 декабря 2011

Вы только учитесь программировать?

Забудьте о нелокальных вещах. Правильный способ сделать это - вернуть var с return var, а затем присвоить результат этого в контексте вызова:

var = inner(airplane)

Edit:

Где вы просто звоните:

planeandoffset(airplane)

Вы ничего не делаете с возвращенными значениями. Чтобы получить к ним доступ:

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

Я не буду анализировать, что вы делаете с этими глобалами, но что бы это ни было, остановитесь. Либо передайте их как параметры между функциями, либо поместите их вместе с вашими функциями в класс и получите доступ к ним как к членам класса.

В любом случае, я предлагаю вам следовать учебному пособию, чтобы изучить более привычный стиль программирования, в котором не используются глобальные значения.

...