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

如何解决Python开发简易银行USSD服务时的UnboundLocalError报错

错误根源

你触发UnboundLocalError: local variable 'AccountNo' referenced before assignment的核心原因是代码逻辑顺序完全颠倒,同时存在USSD交互逻辑错误、方法调用参数不匹配、语法错误三类问题。

具体错误点

  • 直接触发报错的问题:你在text == "1"的分支中,刚输出「请输入账号」的提示,立刻调用了user.select(),既没有传入必填的账号参数,也还没拿到用户输入的账号内容;同时你把接口要返回的USSD提示直接覆盖成了select的返回值,交互逻辑完全错误。
  • User类select方法语法错误:row = list(cursor.fetchall)中fetchall是方法,必须加括号调用,正确写法是cursor.fetchall()。
  • USSD逻辑判断规则全错:USSD的交互中,用户每一步输入的内容会用*拼接,比如用户先选1(已注册用户),再输入账号1234,此时text的值是1*1234,level=2,你原来写的text == "1"+user_response判断条件完全不成立,导致后续逻辑走不通。
  • 方法参数不匹配:
    1. User类定义的insert方法只接收6个参数,你注册分支中传了8个参数,调用会报错。
    2. Bank类的deposit、withdraw方法要求传入Balance参数,你调用时没有传参。
  • 没有全局存储当前登录用户的信息:Bank类的view_balance、show_details方法依赖的用户属性完全没有赋值,调用会报错。

修复方案

第一步:修复User类的select方法

def select(self,accountno):
    dbcon = self.connection()
    select_sql = "select AccountNo,Nameofclient,Age,Gender,Phonenumber,Email,Balance FROM bankuserst WHERE AccountNo=%s"
    cursor = dbcon.cursor()
    try:
        cursor.execute(select_sql, accountno)
        row = cursor.fetchone() # 单账号查询用fetchone更合理,不需要fetchall
        dbcon.close()
        return row
    except Exception as e:
        print("exception", e)
        dbcon.close()
        return None

第二步:修复enterdetails函数的USSD交互逻辑

增加全局变量存储当前登录的用户信息,修正判断条件:

# 全局变量存储当前登录用户信息
current_user = None

@app.route('/', methods=("POST", "GET"))
def enterdetails():
    global current_user
    session_id = request.values.get("sessionId", None)
    service_code = request.values.get("sessionCode", None)
    phone_number = request.values.get("phonenumber", None)
    text = request.values.get("text", "")
    text_array = text.split("*")
    level = len(text_array)
    response = ""
    
    if text == "":
        response = "CON WELCOME To 99's Mobile Banking Service\nAre you a:\n"
        response += "1.Registered Member\n"
        response += "2.New member\n"
    elif level == 1 and text == "1":
        # 第一步选已注册,提示输入账号
        response = "CON WELCOME BACK\nENTER Account Number:\n"
    elif level == 2 and text_array[0] == "1":
        # 拿到用户输入的账号,查询用户
        account_no = text_array[1]
        user_info = user.select(account_no)
        if not user_info:
            response = "END 账号不存在,请重新进入"
        else:
            current_user = user_info
            response = "CON To:\n"
            response += "1.Check Account Balance\n"
            response += "2.Deposit money\n"
            response += "3.Withdraw Cash\n"
            response += "4.Print Account MiniStatement\n"
    elif level ==3 and text_array[0] == "1" and text_array[2] == "1":
        # 查询余额
        if not current_user:
            response = "END 请先登录"
        else:
            response = f"END Your Balance is KSH: {current_user[6]}"
    # 后面的存款、取款、注册逻辑可以参照上面的规则依次修正
    else:
        response = "END Invalid Input"
    return response

其他补充修改建议

  • 移除insert方法调用时多余的参数,和定义保持一致。
  • 不要在交互分支中直接调用deposit、withdraw方法修改余额,等用户输入完金额后再执行修改操作。
  • 注册流程的逻辑也要参照USSD的层级判断规则重新写,每一步对应一个level,依次收集用户的姓名、年龄等信息,最后再执行insert操作。

内容的提问来源于stack exchange,提问作者reappaa99

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:24:03