Переменная не определена после использования ключевого слова «global»

Я пытаюсь сделать камень-ножницы-бумага с помощью графического интерфейса Tkinter, но по какой-то причине в моей функции «запуск» (незаконченной) 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()

хотя я определил это в этих двух функциях (запускаемых кнопками) далее в коде:

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()

Я попробовал установить переменные на global, но это не сработало. Вот весь мой код:

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()

Ни oneplayer, ни twoplayers не вызывается перед run, поэтому эффективно global player_number не выполняется.

Rajdeep Sindhu 11.07.2024 13:33
choose_player_number на самом деле мало что делает, он просто размещает кнопки, но затем run() вызывается до того, как пользователь действительно сможет нажать эти кнопки.
tobias_k 11.07.2024 13:33
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
100
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Решение – неполное

Я исправил код, чтобы решить вашу существующую проблему. Поскольку ваш код сам по себе неполный, я не стал работать над его завершением. Кроме того, это позволит вам дополнить код своей собственной идеей.

Что я наделал

player_number, result, one_player, two_players, title и rock — глобальные переменные в вашем коде. Поскольку не рекомендуется использовать глобальные переменные, я сделал приведенные выше имена переменных клавишами dict. Их значения - я сделал соответствующие значения одинаковыми dict. Когда и когда нам нужно будет вызвать значение, я назову dct['variable_name']. Используя этот метод, мы можем легко избежать использования глобального ключевого слова. (Просто проверьте, нужно ли объявлять переменную computer_input глобальной. Если да, вы можете сделать это так же, как я.)

Над остальной частью кода вам следует работать, исходя из идеи и логики, которые у вас есть в голове.

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

dct = {'player_number' : ''}

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

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


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

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():
    dct['one_player'].grid(column= 2, row=1)
    dct['two_players'].grid(column= 4, row=1)
    
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():
    dct['result'].configure(text= "You Win")

def loose():
    dct['result'].configure(text= "You loose")

def draw():
    dct['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")

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


dct['result'] = Label(window, text= "result will appear here", bg = "green")

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

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

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


add_fillers()
choose_player_number()
run()

window.mainloop()

Глобальные переменные нежелательны в ООП, но в процедурном программировании они необходимы в большинстве случаев. Сейчас глобальный словарь с именем dct действует так же, как глобальное пространство имен.

TheLizzard 11.07.2024 15:07

@TheLizzard, грань между «процедурным» и «объектно-ориентированным» может быть более размытой, чем вы думаете. Если вы не имеете дело с действительно древним языком, в котором нет struct и указателей или ссылок, довольно легко написать осмысленные процедурные программы, в которых доступ ко всем данным осуществляется через ссылки/указатели, которые передаются вверх и вниз по стеку. Одинаково легко (во всех «объектно-ориентированных» языках, которые я когда-либо использовал) объявить глобальные переменные. Но ты прав. С точки зрения инженера-программиста, глобальные переменные плохи в любой парадигме программирования.

Solomon Slow 11.07.2024 16:02
Ответ принят как подходящий

Я пытаюсь сделать камень-ножницы-бумага с помощью графического интерфейса Tkinter, но для по какой-то причине в моей функции «запуска» (незаконченной) player_number равен неопределенный,

Проблема может быть решена.

Просто добавьте параметр player_number в функцию run().

Фрагмент:

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


add_fillers()
choose_player_number()
run(1)

Скриншот:

Вы передаете целое число 1 в run(), но проверяете наличие строки «1» внутри функции.

acw1668 11.07.2024 18:19

Да, но ОП еще не закончен. Как пользователь выберет одного игрока или двух игроков?

toyota Supra 11.07.2024 18:47

Это не имеет ничего общего с ОП, это предоставленное вами решение не имеет смысла.

acw1668 11.07.2024 18:58

Другие вопросы по теме