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

Python报错UnboundLocalError:变量computer_total未赋值即引用

问题分析与解决:UnboundLocalError全局变量引用问题

报错内容

Traceback (most recent call last):
File "main.py", line 58, in
add_total_c()
File "main.py", line 43, in add_total_c
computer_total += computers_card[total_c]
UnboundLocalError: local variable 'computer_total' referenced before assignment

问题原因

Python的作用域规则:当你在函数内部对某个变量执行赋值操作时,Python会自动将该变量视为函数的局部变量,哪怕你已经在全局作用域定义过它。
你代码里的computer_total += computers_card[total_c]本质是computer_total = computer_total + computers_card[total_c],属于赋值操作,所以函数add_total_c会认为computer_total是局部变量,但你没在函数内提前定义它,就触发了报错。

解决方案

方案1:用global关键字声明全局变量

在函数内部开头,用global computer_total明确告诉Python:这个变量是全局作用域的,不是局部的。

方案2:通过函数参数传递+返回值(更推荐)

避免依赖全局变量,把需要计算的卡牌列表作为参数传入函数,计算后返回新的总值,这样代码更模块化,副作用更少。

修复后的代码示例

用global关键字的修复版本

import random

cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
computers_card = []
user_card = []
computer_total = 0
user_total = 0

def deal_computer():
    for _ in range(2):  # 简化循环写法,无需用到循环变量
        # 修复索引越界问题:randint是闭区间,原len(cards)改为len(cards)-1
        computers_card.append(cards[random.randint(0, len(cards)-1)])

def deal_user():
    for _ in range(2):
        user_card.append(cards[random.randint(0, len(cards)-1)])

def initial_cards():
    deal_computer()
    deal_user()

def add_total_c():
    global computer_total  # 声明为全局变量
    computer_total = 0  # 每次计算前重置,避免重复累加
    for card in computers_card:  # 直接遍历列表元素,更简洁
        computer_total += card

def add_total_u():
    global user_total
    user_total = 0
    for card in user_card:
        user_total += card

# 调整打印顺序:先初始化卡牌再打印
initial_cards()
print(f"Your cards: {user_card}")
print(f"Computer's first card: {computers_card[0]}")  # 符合游戏逻辑,只显示电脑首张牌

choice = input("Type 'y' for another card or 'n' to stand with your current cards: ")

if choice == "n":
    add_total_c()
    add_total_u()

    stand = True
    while stand:
        if 17 < computer_total < 21:
            if user_total > computer_total:
                print("You Won!")
            else:
                print("You Lose!")
            stand = False
        
        if computer_total <= 17:
            computers_card.append(cards[random.randint(0, len(cards)-1)])
            add_total_c()
            if computer_total > 21:
                print("Computer Bust! You Won!")
                stand = False

用参数+返回值的优化版本(更健壮)

import random

cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]

def deal_cards():
    # 抽取两张牌,返回卡牌列表
    return [cards[random.randint(0, len(cards)-1)] for _ in range(2)]

def calculate_total(cards_list):
    # 计算卡牌总值,同时处理A牌的特殊情况(总值超21时11转1)
    total = sum(cards_list)
    if 11 in cards_list and total > 21:
        total -= 10
    return total

# 初始化卡牌
user_card = deal_cards()
computers_card = deal_cards()

print(f"Your cards: {user_card}, current total: {calculate_total(user_card)}")
print(f"Computer's first card: {computers_card[0]}")

choice = input("Type 'y' for another card or 'n' to stand with your current cards: ")

if choice == "n":
    user_total = calculate_total(user_card)
    computer_total = calculate_total(computers_card)

    stand = True
    while stand:
        if 17 < computer_total < 21:
            if user_total > computer_total:
                print("You Won!")
            else:
                print("You Lose!")
            stand = False
        
        if computer_total <= 17:
            computers_card.append(cards[random.randint(0, len(cards)-1)])
            computer_total = calculate_total(computers_card)
            if computer_total > 21:
                print("Computer Bust! You Won!")
                stand = False

额外说明

  • 原代码random.randint(0, len(cards))会触发索引越界,因为列表索引范围是0到len(cards)-1,需调整参数
  • 原代码打印初始卡牌的语句放在初始化函数之前,会输出空列表,已调整顺序
  • 优化版本加入了A牌的逻辑处理,更贴合真实21点游戏规则

内容的提问来源于stack exchange,提问作者Carlos Colón

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 03:05:57