Python3 UnboundLocalError求助:port变量赋值前被引用
解决UnboundLocalError:局部变量'port'在赋值前被引用
我来帮你搞定这个报错,咱们先拆解问题根源,再一步步修复:
错误原因分析
你看rlogin函数里的这行代码:
port = port
这行完全是多余的,而且会触发错误:Python会把port当成局部变量,但你既没在函数内部给它赋值,也没通过参数把外部的port传进来,自然就会报错“局部变量在赋值前被引用”。另外,你调用s.login的时候也没传port参数,就算port变量没问题,登录也会用默认的SSH端口22,而不是你选的端口。
修复步骤
1. 修改rlogin函数,接收port参数
把函数定义改成接收host和port两个参数,删掉多余的port = port,并在登录时传入port:
def rlogin(host, port): s = pxssh.pxssh() hostname = host username = getuser() password = getpass('password: ') # 移除错误的port = port行 s.PROMPT = r"r\s+>$|\s+> $|\s+#$|\s+# $" # 加r前缀表示原始字符串,避免转义问题 # 登录时传入port参数 s.login(hostname, username, password, port=port, auto_prompt_reset=False) print("Logging into Console Port...") s.prompt(timeout=10) print ("Good to Go! Press Enter") print () s.interact() sys.exit()
2. 在main函数中调用rlogin时传入port参数
修改main里的调用逻辑,把获取到的port传进去,同时给host做去换行处理(避免文件读取的换行符影响登录):
if choice==2: host = idf_menu() print(host.strip()) # 去掉host字符串里的换行符 port = port_menu() # port_menu已经返回整数,不需要再int()转换 print(port) rlogin(host.strip(), port) # 传入host和port
3. 优化port_menu函数的错误处理
原来的port_menu在用户输入错误时会返回0,这会导致用错误端口登录。改成错误输入后不返回,继续循环让用户重新选择:
def port_menu(): print (30 * "-" , "MENU" , 30 * "-") print ("1. Switch A") print ("2. Switch B") print ("3. Switch C") print ("4. VSwitch A") print ("5. Vswitch B") print ("B. Go Back") print ("X. Exit") print (67 * "_") while True: choice = input("Enter your port choice [1-5]: ").lower() # 统一转小写,支持大写B/X if choice=="1": return 2002 elif choice=="2": return 2003 elif choice=="3": return 2004 elif choice=="4": return 2010 elif choice=="5": return 2011 elif choice=="b": main() elif choice=="x": print("Whatever! BYE!!") sys.exit() else: print("WRONG!!!! Please enter a valid option (1-5, B, X)") # 不返回,继续循环让用户重新输入
4. 优化idf_menu的递归问题(可选但推荐)
原来的idf_menu在用户输入错误或返回上级时用递归调用,多次操作可能导致栈溢出。改成循环结构更稳妥:
def idf_menu(): while True: devlist = [] with open('obb-devs-idf','r') as devicesfile: i = 1 hosts = devicesfile.readlines() for host in hosts: host_clean = host.strip() print(i,"-",host_clean) i += 1 devlist.append(host_clean) print("B. Go Back") print("X. Exit") d = input(f"Select Console Router [1-{i-1}]: ").lower() if d=="b": main() elif d=="x": print("Bye!") sys.exit() elif d.isdigit(): selected = int(d) - 1 if 0 <= selected < len(devlist): # 增加边界检查,避免索引越界 return devlist[selected] else: print(f"Invalid choice! Please enter a number between 1 and {i-1}") else: print("Invalid Choice, try again")
完整修复后的代码
#!/usr/bin/python36 import sys import logging import re import os from pexpect import pxssh from getpass import getuser,getpass os.chdir("/app/network-scripts/oob/") username = getuser() def first_menu(): print() print("Current Working Directory: ", os.getcwd()) print() print (30 * "-" , "MENU" , 30 * "-") print ("1. Data Center") print ("2. IDF") print ("0. Exit") print (67 * "_") def idf_menu(): while True: devlist = [] with open('obb-devs-idf','r') as devicesfile: i = 1 hosts = devicesfile.readlines() for host in hosts: host_clean = host.strip() print(i,"-",host_clean) i += 1 devlist.append(host_clean) print("B. Go Back") print("X. Exit") d = input(f"Select Console Router [1-{i-1}]: ").lower() if d=="b": main() elif d=="x": print("Bye!") sys.exit() elif d.isdigit(): selected = int(d) - 1 if 0 <= selected < len(devlist): return devlist[selected] else: print(f"Invalid choice! Please enter a number between 1 and {i-1}") else: print("Invalid Choice, try again") def port_menu(): print (30 * "-" , "MENU" , 30 * "-") print ("1. Switch A") print ("2. Switch B") print ("3. Switch C") print ("4. VSwitch A") print ("5. Vswitch B") print ("B. Go Back") print ("X. Exit") print (67 * "_") while True: choice = input("Enter your port choice [1-5]: ").lower() if choice=="1": return 2002 elif choice=="2": return 2003 elif choice=="3": return 2004 elif choice=="4": return 2010 elif choice=="5": return 2011 elif choice=="b": main() elif choice=="x": print("Whatever! BYE!!") sys.exit() else: print("WRONG!!!! Please enter a valid option (1-5, B, X)") def rlogin(host, port): s = pxssh.pxssh() hostname = host username = getuser() password = getpass('password: ') s.PROMPT = r"r\s+>$|\s+> $|\s+#$|\s+# $" s.login(hostname, username, password, port=port, auto_prompt_reset=False) print("Logging into Console Port...") s.prompt(timeout=10) print ("Good to Go! Press Enter") print () s.interact() sys.exit() def main(): while True: first_menu() try: choice = int(input("Enter your Choice: ")) except ValueError: print("Please enter a valid number!") continue if choice==1: print("THIS DOESN'T WORK YET!!") print("TRY AGAIN!!") elif choice==2: host = idf_menu() print(host) port = port_menu() print(port) rlogin(host, port) elif choice==0: print("Whatever. Bye.") sys.exit() else: print("Invalid Choice! Please enter 0, 1, or 2") if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) main()
现在测试一下,应该就能正常选择端口并通过SSH连接了,不会再出现UnboundLocalError错误。
内容的提问来源于stack exchange,提问作者Ippy
相关产品推荐
相关产品推荐

