简体   繁体   English

在Python中重用内部函数

[英]Reuse of an inner function in Python

I'm trying to figure out how to use a Python 3 function (using nonlocal variables) within more than one other function without defining it all over again. 我试图弄清楚如何在一个以上的函数中使用Python 3函数(使用非局部变量)而不重新定义它。 Here's a very simplified example of what I mean: 这是我的意思的一个非常简单的例子:

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")

I'm getting an error ( SyntaxError: No binding for nonlocal 'var' found ) but I suspect I'm doing this very wrongly. 我收到错误消息( SyntaxError: No binding for nonlocal 'var' found ),但我怀疑自己做错了。 I don't ever intend to run inner() on its own. 我不打算自己运行inner() How do I reuse inner() the right way? 如何以正确的方式重用inner() I can't just define it inside outer1() and then reuse it in outer2() , can I? 我不能只在outer1()内定义它,然后在outer2()重用它,可以吗?

Okay, by uh...popular demand...here's the relevant section of my code... 好的,呃...受欢迎的需求...这是我代码的相关部分...

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)

Are you just learning to programme? 您只是在学习编程吗?

Forget about nonlocal anything. 忘记非本地的任何事情。 The correct way to do this is to return var with return var , and then assign the result of that in the calling context: 正确的方法是用var return var ,然后在调用上下文中分配结果:

var = inner(airplane)

Edit: 编辑:

Where you are simply calling: 你在哪里打电话:

planeandoffset(airplane)

You are not doing anything with the values returned. 您没有对返回的值执行任何操作。 To access them do: 要访问它们:

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

I'm not going to analyse what you're doing with those globals, but whatever it is, stop. 我不会分析您对这些全局变量所做的事情,但是无论如何,请停止。 Either pass those as parameters between functions, or put them, together with your functions, in a class, and access them as members of the class. 可以将它们作为参数在函数之间传递,或者将它们与您的函数一起放在一个类中,然后作为类的成员进行访问。

Either way, I suggest that you follow a tutorial to learn a more usual style of programming that doesn't use globals. 无论哪种方式,我都建议您按照教程学习不使用全局变量的更常用的编程风格。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM