为何Python代码try块正常执行却触发异常返回False?
loadData函数异常返回False的问题分析
我写了一段用于学校项目的Python代码,运行时发现尽管try块里的逻辑看似正常执行,但loadData函数始终会进入except块返回False,导致测试失败。我怀疑是while循环的问题,但不确定具体原因,希望有人帮忙分析。
原代码
allAirports = [] allFlights = {} def loadData(airportFile, flightFile): try: airFile = open(airportFile, "r") fileFlight = open(flightFile, "r") while True: line = airFile.readline() line = line.replace(' ', '') line = line.replace(' ', '') airList = list(line.split(',')) airList[-1] = airList[-1].strip() if airList[0] == '': line1 = fileFlight.readline() line1 = line1.replace(' ', '') line1 = line1.replace(' ', '') line1 = line1.replace(' ', '') flightList = list(line1.split(',')) flightList[-1] = flightList[-1].strip() for i in range (1): line2 = getAirportByCode(flightList[1]) line2 = line2.replace('(', ' ') line2 = line2.replace(')', ' ') line2 = line2.replace(',', ' ') line2 = line2.split() line2[1] = re.sub(r"([A-Z])", r" \1", line2[1]).lstrip() line2[2] = re.sub(r"([A-Z])", r" \1", line2[2]).lstrip() line3 = getAirportByCode(flightList[2]) line3 = line3.replace('(', ' ') line3 = line3.replace(')', ' ') line3 = line3.replace(',', ' ') line3 = line3.split() line3[1] = re.sub(r"([A-Z])", r" \1", line3[1]).lstrip() line3[2] = re.sub(r"([A-Z])", r" \1", line3[2]).lstrip() if flightList[1] in allFlights: allFlights[flightList[1]] += [Flight(flightList[0], Airport(line2[0], line2[1], line2[2]), Airport(line3[0], line3[1], line3[2]))] else: allFlights.setdefault(flightList[1], []) allFlights[flightList[1]] += [Flight(flightList[0], Airport(line2[0], line2[1], line2[2]), Airport(line3[0], line3[1], line3[2]))] else: allAirports.append(Airport(airList[0], airList[1], airList[2])) except: return False def getAirportByCode(code): code1 = code for i in range (len(allAirports)): if code1 in str(allAirports[i]): return (str(allAirports[i]).replace(' ', '')) return -1 t1 = loadData("airports.txt", "flights.txt") total = 0 for i in allFlights: total += len(allFlights[i]) print(t1) if t1 and len(allAirports) == 37 and total == 146: print("Test 4 Passed. (loadData())") else: print("Test 4 Failed. (loadData())")
问题根源
无限循环引发的索引越界错误
你的while True没有终止条件,当airFile.readline()读到文件末尾时会返回空字符串,此时airList = list(line.split(','))得到[''],触发airList[0] == ''的分支。接着去读fileFlight.readline(),当航班文件也读到末尾时,line1是空字符串,处理后flightList同样是[''],之后调用getAirportByCode(flightList[1])会因为flightList只有一个元素而抛出IndexError,直接触发except块返回False。缺失的模块导入
代码里使用了re.sub但没有导入re模块,会抛出ImportError,同样会进入except块。不可靠的机场匹配逻辑
getAirportByCode通过把Airport对象转成字符串再匹配代码,这种方式非常脆弱——如果Airport的__str__方法格式变化,匹配就会失效,而且容易出现误匹配。冗余代码与资源泄漏
for i in range(1)完全是多余的,没有实际作用。- 打开文件后没有关闭,会造成资源泄漏,最好用
with语句管理文件。
修复后的代码
import re allAirports = [] allFlights = {} # 补全缺失的类定义(原代码里应该有但没贴出来) class Airport: def __init__(self, code, city, country): self.code = code self.city = city self.country = country class Flight: def __init__(self, flight_num, dep_airport, arr_airport): self.flight_num = flight_num self.dep_airport = dep_airport self.arr_airport = arr_airport def loadData(airportFile, flightFile): try: # 用with语句自动管理文件,无需手动关闭 with open(airportFile, "r") as airFile, open(flightFile, "r") as fileFlight: # 先读取所有机场数据 for line in airFile: line = line.strip().replace(' ', '') if not line: continue air_code, city, country = line.split(',') allAirports.append(Airport(air_code.strip(), city.strip(), country.strip())) # 再读取所有航班数据 for line in fileFlight: line = line.strip().replace(' ', '') if not line: continue flight_num, dep_code, arr_code = line.split(',') dep_airport = getAirportByCode(dep_code.strip()) arr_airport = getAirportByCode(arr_code.strip()) # 跳过无效的机场数据 if not dep_airport or not arr_airport: continue # 更新航班字典 if dep_code in allFlights: allFlights[dep_code].append(Flight(flight_num, dep_airport, arr_airport)) else: allFlights[dep_code] = [Flight(flight_num, dep_airport, arr_airport)] return True except Exception as e: # 打印错误信息方便调试 print(f"调试信息: {str(e)}") return False def getAirportByCode(code): # 直接对比机场对象的code属性,更可靠 for airport in allAirports: if airport.code == code: return airport return None t1 = loadData("airports.txt", "flights.txt") total = sum(len(flights) for flights in allFlights.values()) print(t1) if t1 and len(allAirports) == 37 and total == 146: print("Test 4 Passed. (loadData())") else: print("Test 4 Failed. (loadData())")
修复说明
- 用
with语句管理文件,自动关闭,避免资源泄漏。 - 分开读取机场和航班文件,逻辑更清晰,避免混合读取的混乱。
- 重构
getAirportByCode,直接对比对象属性,匹配逻辑更可靠。 - 添加异常信息打印,方便调试定位问题。
- 去掉冗余的循环和无效的空格处理,简化代码。
- 补全了原代码缺失的
Airport和Flight类定义(原代码里应该存在但未粘贴)。
内容的提问来源于stack exchange,提问作者Kibi Karan
相关产品推荐
相关产品推荐

