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

使用global关键字后仍提示player_number未定义的Tkinter问题

Tkinter石头剪刀布程序player_number未定义问题解决

问题情况

我用Tkinter开发带GUI的石头剪刀布程序,未完成的run()函数里提示player_number未定义:

def run():
    result.grid(column=3, row=1)
    if player_number == "1":
        rock.grid(column=2, row=2)


add_fillers()
choose_player_number()
run()

虽然我在按钮触发的两个函数里用global定义了这个变量:

def oneplayer():
    title.configure(text = "One player")
    title.grid(column=3, row=0)
    global player_number
    player_number = "1"
    one_player.destroy()
    two_players.destroy()


def twoplayers():
    title.configure(text = "Two players")
    title.grid(column=3, row=0)
    global player_number
    player_number = "2"
    one_player.destroy()
    two_players.destroy()

完整代码如下:

import random
from random import randint
import tkinter as tk
from tkinter import *

window = tk.Tk()
window.geometry("1400x860")
window.title = "Rock paper scissors"

result = Label(window, text= "result will appear here", bg="green")

def oneplayer():
    title.configure(text = "One player")
    title.grid(column=3, row=0)
    global player_number
    player_number = "1"
    one_player.destroy()
    two_players.destroy()


def twoplayers():
    title.configure(text = "Two players")
    title.grid(column=3, row=0)
    global player_number
    player_number = "2"
    one_player.destroy()
    two_players.destroy()

one_player = Button(window, text = "One Player", command = oneplayer)
two_players = Button(window, text= "Two players", command = twoplayers)

title = Label(window, text = "Rock paper scissors" , bg= "blue", fg = "white", font= "Times")
title.grid(column=3, row=0)


def add_fillers():
    filler = Label(window, text = "                                                                   ")
    filler.grid(column=1, row=0)
    filler2 = Label(window, text = "                                                                   ")
    filler2.grid(column=0, row=0)
    filler3 = Label(window, text = "                                       ")
    filler3.grid(column=2, row=0)

def choose_player_number():
    one_player.grid(column= 2, row=1)
    two_players.grid(column= 4, row=1)
    
computer_input = ""

def computer_choice():
    computer_input = randint("1", "2", "3")
    if computer_input == "1":
        computer_value = "Rock"
    elif computer_input == "2":
        computer_value = "paper"
    else:
        computer_value = "scissors"
    computer_result = Label(window, text= "the computer's choice was:" + computer_value)

    return computer_input

def win():
    result.configure(text= "You Win")

def loose():
    result.configure(text= "You loose")

def draw():
    result.configure(text= "Draw")

def evaluate_rock():
    computer_choice()
    if computer_input == "3":
        win()
    elif computer_input == "2":
        loose()
    elif computer_input == "1":
        draw()
    else:
        print ("error")

rock = Button(window, text="Rock", command= evaluate_rock, fg="green", bg="blue")


def run():
    result.grid(column=3, row=1)
    if player_number == "1":
        rock.grid(column=2, row=2)


add_fillers()
choose_player_number()
run()

window.mainloop()

问题原因

  1. 程序启动时直接调用了run(),此时用户还未点击任何选择按钮,player_number全局变量根本没被初始化,直接访问会报错。
  2. run()函数内没有声明global player_number,即使后续用户点击按钮初始化了变量,函数也无法访问全局作用域的player_number。

解决步骤

  1. 全局初始化变量:在代码开头先定义player_number的初始值,避免程序启动时的报错:
    player_number = ""
    
  2. 在run()中声明全局变量:修改run()函数,添加global声明:
    def run():
        global player_number
        result.grid(column=3, row=1)
        if player_number == "1":
            rock.grid(column=2, row=2)
    
  3. 调整run()的调用时机:不要在程序启动时直接调用run(),而是放到oneplayer()和twoplayers()函数末尾,确保用户选择后再执行:
    def oneplayer():
        title.configure(text = "One player")
        title.grid(column=3, row=0)
        global player_number
        player_number = "1"
        one_player.destroy()
        two_players.destroy()
        run()  # 用户选择后再执行run逻辑
    
    def twoplayers():
        title.configure(text = "Two players")
        title.grid(column=3, row=0)
        global player_number
        player_number = "2"
        one_player.destroy()
        two_players.destroy()
        run()  # 用户选择后再执行run逻辑
    
  4. 修复其他代码问题:
    • window.title应该用方法赋值:window.title("Rock paper scissors"),而不是直接赋值属性。
    • computer_choice()中randint用法错误,应该传入整数范围randint(1,3),再转字符串:
      def computer_choice():
          computer_num = randint(1,3)
          computer_input = str(computer_num)
          if computer_input == "1":
              computer_value = "Rock"
          elif computer_input == "2":
              computer_value = "paper"
          else:
              computer_value = "scissors"
          computer_result = Label(window, text= "the computer's choice was:" + computer_value)
          computer_result.grid()  # 需要将标签布局到窗口
          return computer_input
      
    • evaluate_rock()中需要接收computer_choice()的返回值:
      def evaluate_rock():
          global computer_input
          computer_input = computer_choice()
          if computer_input == "3":
              win()
          elif computer_input == "2":
              loose()
          elif computer_input == "1":
              draw()
          else:
              print ("error")
      

修改后的完整代码

import random
from random import randint
import tkinter as tk
from tkinter import *

window = tk.Tk()
window.geometry("1400x860")
window.title("Rock paper scissors")  # 修复title赋值方式

player_number = ""  # 全局初始化变量
result = Label(window, text= "result will appear here", bg="green")

def oneplayer():
    title.configure(text = "One player")
    title.grid(column=3, row=0)
    global player_number
    player_number = "1"
    one_player.destroy()
    two_players.destroy()
    run()  # 用户选择后执行run


def twoplayers():
    title.configure(text = "Two players")
    title.grid(column=3, row=0)
    global player_number
    player_number = "2"
    one_player.destroy()
    two_players.destroy()
    run()  # 用户选择后执行run

one_player = Button(window, text = "One Player", command = oneplayer)
two_players = Button(window, text= "Two players", command = twoplayers)

title = Label(window, text = "Rock paper scissors" , bg= "blue", fg = "white", font= "Times")
title.grid(column=3, row=0)


def add_fillers():
    filler = Label(window, text = "                                                                   ")
    filler.grid(column=1, row=0)
    filler2 = Label(window, text = "                                                                   ")
    filler2.grid(column=0, row=0)
    filler3 = Label(window, text = "                                       ")
    filler3.grid(column=2, row=0)

def choose_player_number():
    one_player.grid(column= 2, row=1)
    two_players.grid(column= 4, row=1)
    
computer_input = ""

def computer_choice():
    computer_num = randint(1,3)  # 修复randint用法
    computer_input = str(computer_num)
    if computer_input == "1":
        computer_value = "Rock"
    elif computer_input == "2":
        computer_value = "paper"
    else:
        computer_value = "scissors"
    computer_result = Label(window, text= "the computer's choice was:" + computer_value)
    computer_result.grid(column=3, row=3)  # 布局标签到窗口
    return computer_input

def win():
    result.configure(text= "You Win")

def loose():
    result.configure(text= "You loose")

def draw():
    result.configure(text= "Draw")

def evaluate_rock():
    global computer_input
    computer_input = computer_choice()  # 接收返回值
    if computer_input == "3":
        win()
    elif computer_input == "2":
        loose()
    elif computer_input == "1":
        draw()
    else:
        print ("error")

rock = Button(window, text="Rock", command= evaluate_rock, fg="green", bg="blue")


def run():
    global player_number
    result.grid(column=3, row=1)
    if player_number == "1":
        rock.grid(column=2, row=2)


add_fillers()
choose_player_number()
# 移除启动时的run()调用

window.mainloop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:12:09