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

Python已预定义变量被识别为局部变量的问题解决

问题:修改全局棋盘变量时触发UnboundLocalError错误

已提前将变量A1、A2等初始化为空格,想通过player1_move函数根据用户输入修改这些变量,但触发UnboundLocalError,提示local variable 'A1' referenced before assignment。推测Python将A1识别为函数内的局部变量,请问该如何修复这个错误?

代码示例

A1 = ""
A2 = " "
A3 = " "
B1 = " "
B2 = " "
B3 = " "
C1 = " "
C2 = " "
C3 = " "

def board():
    print(f"""  1   2   3 
    A {A1}---{A2}---{A3}
      |\  |  /|
      | \ | / |
      |  \|/  |
     B {B1}---{B2}---{B3}
      |  /|\  |
      | / | \ |
      |/  |  \|
     G {C1}---{C2}---{C3}""")

board()
def player1_move(x):

    if x.title() == "A1":
        if A1 == " ":
            A1 = "x"
            board()
        else:
            print("This place is taken!" + "\nEnter another one!")

player1move1 = input("Player 1 moves first!" + "\nEnter your first move! :")
player1_move(player1move1)

错误信息

Traceback (most recent call last):
  File "/home/noname/Documents/PythonProjects/Assignment/dummy_file1.py", line 34, in <module>
    player1_move(player1move1)
  File "/home/noname/Documents/PythonProjects/Assignment/dummy_file1.py", line 27, in player1_move
    if A1 == " ":
UnboundLocalError: local variable 'A1' referenced before assignment

解决方案

错误原因

Python的作用域规则:如果函数内部对变量有赋值操作,会默认将该变量判定为局部变量,哪怕外部存在同名全局变量。你在player1_move函数中先判断A1 == " ",后续又执行A1 = "x"赋值,Python会把A1当作局部变量,但判断时局部变量还未定义,因此抛出UnboundLocalError。

方法1:用global声明全局变量

在函数内部开头,明确声明要使用的全局变量,告诉Python该变量来自外部全局作用域,而非局部:

def player1_move(x):
    # 声明要操作的全局变量
    global A1
    if x.title() == "A1":
        if A1 == " ":
            A1 = "x"
            board()
        else:
            print("This place is taken!\nEnter another one!")

如果后续需要修改A2、B1等其他全局变量,只需在global后添加对应的变量名,比如global A1, A2, B1。

方法2:用字典存储棋盘状态(更推荐)

全局变量过多会导致代码维护难度上升,更合理的方式是将所有棋盘状态存入一个字典,避免零散的全局变量:

# 用字典统一存储棋盘位置与状态
board_state = {
    "A1": "",
    "A2": " ",
    "A3": " ",
    "B1": " ",
    "B2": " ",
    "B3": " ",
    "C1": " ",
    "C2": " ",
    "C3": " "
}

def board():
    print(f"""  1   2   3 
    A {board_state["A1"]}---{board_state["A2"]}---{board_state["A3"]}
      |\  |  /|
      | \ | / |
      |  \|/  |
     B {board_state["B1"]}---{board_state["B2"]}---{board_state["B3"]}
      |  /|\  |
      | / | \ |
      |/  |  \|
     G {board_state["C1"]}---{board_state["C2"]}---{board_state["C3"]}""")

board()

def player1_move(x):
    pos = x.title()
    # 先校验输入位置是否合法
    if pos not in board_state:
        print("Invalid position! Enter a valid one like A1, B2.")
        return
    if board_state[pos] in (" ", ""):
        board_state[pos] = "x"
        board()
    else:
        print("This place is taken!\nEnter another one!")

player1move1 = input("Player 1 moves first!\nEnter your first move! :")
player1_move(player1move1)

这种方式无需global声明,代码结构更清晰,还能轻松扩展位置合法性校验,后续添加玩家2移动等功能也更方便。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:40:39