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
相关产品推荐
相关产品推荐

