尝试设置全局对象,但在尝试从另一个文件访问子类时未定义获取 NameError 对象
Trying to set up global object, but getting NameError object is not defined when trying to access subclass from another file
我试图了解 Python classes 如何工作以遵循 OOP 的四大支柱。
我正在尝试设置一个控制器 class,它将设置一些 UI classes 并响应输入。当前控制器 class 初始化一个框架,该框架初始化一些按钮。控制器将 click(x,y) 函数传递给 UI classes 以监听点击。该部分目前正在工作,但我似乎无法弄清楚控制器 class 如何访问它的子 class 以对 UI.
进行更改
这是我目前得到的代码。我的问题是控制器中的 Click(x,y) 函数似乎无法找到在 main.
中创建的 "game" 对象
Controller.py:
from GameFrame import GameFrame
global game
def click(x, y):
global game
print("%s %s" %(x,y))
game.changeColor(x, y)
if __name__ == '__main__':
global game
game = GameFrame("title", click)
pass
GameFrame.py:
from GameButtons import GameButtons
from tkinter import *
class GameFrame(object):
global gameButtons
def __init__(self, params, click):
frame = Tk()
gameButtons= GameButtons(frame,click)
frame.mainloop()
def changeColor(self, x, y):
gameButtons.buttons[x][y].configure(bg = "green")
GameButtons.py:
from tkinter import *
class GameButtons(object):
global buttons
buttons = [[0 for x in range(8)]for x in range(8)]
def __init__(self, frame, click):
for x in range(8):
for y in range(8):
b = Button(frame, text = " x ", command = lambda row = x, col = y: click(row, col))
b.grid(row = x, column = y)
global buttons
buttons[x][y] = b
单击按钮正确地从 click(x,y) 函数输出 row/column 但随后给我一个 NameError: name 'game' is not defined when trying to 运行 game.changeColor(x,y)
非常感谢任何解决这个问题的帮助,或者任何解释为什么我试图实现的首先是一个坏主意。
问题是你永远不会给 GameFrame
一个完成初始化的机会,因为 mainloop
不会 return 直到 window 被销毁。因此,由于初始化永远不会完成,因此 game
未正确初始化。
简单的解决方法是将对 mainloop
的调用移到初始化函数之外,以便可以正确初始化对象。您的主要代码应如下所示:
if __name__ == '__main__':
game = GameFrame("title", click)
game.start()
然后,你需要在GameFrame
中定义一个start
方法。这将要求您持有对根 window 的引用。我会这样写:
class GameFrame(object):
def __init__(self, params, click):
self.root = Tk()
gameButtons = GameButtons(self.root, click)
def start(self):
self.root.mainloop()
注意:如果你的目标是真正的面向对象,你需要移除对全局变量的依赖。
这是您重写的代码,因此它不使用全局变量,game
除外,它本质上是全局变量:
from tkinter import *
class GameButtons(object):
def __init__(self, frame, click):
self.buttons = [[None for x in range(8)] for x in range(8)]
for x in range(8):
for y in range(8):
b = Button(frame, text = " x ", command = lambda row = x, col = y: click(row, col))
self.buttons[x][y] = b
b.grid(row = x, column = y)
class GameFrame(object):
def __init__(self, params, click):
self.root = Tk()
self.gameButtons= GameButtons(self.root,click)
def changeColor(self, x, y):
self.gameButtons.buttons[x][y].configure(bg = "green")
def start(self):
self.root.mainloop()
def click(x, y):
print("%s %s" %(x,y))
game.changeColor(x, y)
if __name__ == '__main__':
game = GameFrame("title", click)
game.start()
我试图了解 Python classes 如何工作以遵循 OOP 的四大支柱。
我正在尝试设置一个控制器 class,它将设置一些 UI classes 并响应输入。当前控制器 class 初始化一个框架,该框架初始化一些按钮。控制器将 click(x,y) 函数传递给 UI classes 以监听点击。该部分目前正在工作,但我似乎无法弄清楚控制器 class 如何访问它的子 class 以对 UI.
进行更改这是我目前得到的代码。我的问题是控制器中的 Click(x,y) 函数似乎无法找到在 main.
中创建的 "game" 对象Controller.py:
from GameFrame import GameFrame
global game
def click(x, y):
global game
print("%s %s" %(x,y))
game.changeColor(x, y)
if __name__ == '__main__':
global game
game = GameFrame("title", click)
pass
GameFrame.py:
from GameButtons import GameButtons
from tkinter import *
class GameFrame(object):
global gameButtons
def __init__(self, params, click):
frame = Tk()
gameButtons= GameButtons(frame,click)
frame.mainloop()
def changeColor(self, x, y):
gameButtons.buttons[x][y].configure(bg = "green")
GameButtons.py:
from tkinter import *
class GameButtons(object):
global buttons
buttons = [[0 for x in range(8)]for x in range(8)]
def __init__(self, frame, click):
for x in range(8):
for y in range(8):
b = Button(frame, text = " x ", command = lambda row = x, col = y: click(row, col))
b.grid(row = x, column = y)
global buttons
buttons[x][y] = b
单击按钮正确地从 click(x,y) 函数输出 row/column 但随后给我一个 NameError: name 'game' is not defined when trying to 运行 game.changeColor(x,y)
非常感谢任何解决这个问题的帮助,或者任何解释为什么我试图实现的首先是一个坏主意。
问题是你永远不会给 GameFrame
一个完成初始化的机会,因为 mainloop
不会 return 直到 window 被销毁。因此,由于初始化永远不会完成,因此 game
未正确初始化。
简单的解决方法是将对 mainloop
的调用移到初始化函数之外,以便可以正确初始化对象。您的主要代码应如下所示:
if __name__ == '__main__':
game = GameFrame("title", click)
game.start()
然后,你需要在GameFrame
中定义一个start
方法。这将要求您持有对根 window 的引用。我会这样写:
class GameFrame(object):
def __init__(self, params, click):
self.root = Tk()
gameButtons = GameButtons(self.root, click)
def start(self):
self.root.mainloop()
注意:如果你的目标是真正的面向对象,你需要移除对全局变量的依赖。
这是您重写的代码,因此它不使用全局变量,game
除外,它本质上是全局变量:
from tkinter import *
class GameButtons(object):
def __init__(self, frame, click):
self.buttons = [[None for x in range(8)] for x in range(8)]
for x in range(8):
for y in range(8):
b = Button(frame, text = " x ", command = lambda row = x, col = y: click(row, col))
self.buttons[x][y] = b
b.grid(row = x, column = y)
class GameFrame(object):
def __init__(self, params, click):
self.root = Tk()
self.gameButtons= GameButtons(self.root,click)
def changeColor(self, x, y):
self.gameButtons.buttons[x][y].configure(bg = "green")
def start(self):
self.root.mainloop()
def click(x, y):
print("%s %s" %(x,y))
game.changeColor(x, y)
if __name__ == '__main__':
game = GameFrame("title", click)
game.start()