You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:17:42