在Python中重用内部函数
我正在尝试弄清楚如何在多个函数中使用一个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
你刚开始学习编程吗?
那就先别管什么“非局部变量”了。正确的做法是用 return var
来返回 var
,然后在调用的地方把这个结果赋值给一个变量:
var = inner(airplane)
补充:
如果你只是简单地调用了:
planeandoffset(airplane)
那么你其实并没有对返回的值做任何处理。要想使用这些值,可以这样做:
airplane, linename, latstart, latend, lonstart, lonend = planeandoffset(airplane)
我不打算分析你是怎么使用那些全局变量的,但无论你在做什么,建议你停下来。要么把这些变量作为参数传递给函数,要么把它们和你的函数放在一个类里面,然后作为类的成员来访问。
不管怎样,我建议你跟着一个教程学习一种更常见的编程风格,这种风格不使用全局变量。