Python Tkinter:如何在不断变化的 class 中避免使用全局变量?

Python Tkinter: How do I avoid global variables in a changing class?

我目前正在做一个大型项目来帮助我学习我的第一门编程语言 (Python),并且我 运行 进入了一些未知的领域。我知道使用全局变量通常是不好的并且有更好的解决方案,但我无法根据我的情况弄清楚。

我将下面的代码作为我想要实现的目标的简单示例。执行此操作而不是使用全局变量的最佳方法是什么?

此外,我在下面的代码中是否犯了任何一般性错误?

提前致谢

from tkinter import *

root = Tk()

display_number = 5


class NumberBox():
    def __init__(self):
        global display_number
        self.number_label = Label(root, text=display_number)
        self.number_label.pack()
        self.engine()

    def engine(self):
        self.number_label.config(text=display_number)
        root.after(10, self.engine)


def change_number(operation):
    global display_number
    if operation == "add":
        display_number += 1
    if operation == "subtract":
        display_number -= 1

Button(root, text="Add Class", command=lambda: NumberBox()).pack()
Button(root, text="Number UP", command=lambda: change_number("add")).pack()
Button(root, text="Number DOWN", command=lambda: change_number("subtract")).pack()

for _ in range(5):
    NumberBox()

root.mainloop()

像这样:

from tkinter import *

root = Tk()

class NumberBox():
    display_number = 5
    def __init__(self):
        self.number_label = Label(root, text=self.display_number)
        self.number_label.pack()
        self.engine()

    def engine(self):
        self.number_label.config(text=self.display_number)
        root.after(10, self.engine)


def change_number(operation):
    if operation == "add":
        NumberBox.display_number += 1
    if operation == "subtract":
        NumberBox.display_number -= 1

Button(root, text="Add Class", command=lambda: NumberBox()).pack()
Button(root, text="Number UP", command=lambda: change_number("add")).pack()
Button(root, text="Number DOWN", command=lambda: change_number("subtract")).pack()

for _ in range(5):
    NumberBox()

root.mainloop()

通过在 class 中定义变量(但在 __init__ 之外,它作为单个变量由 class 的所有实例拥有,因此在一个变量中更改它会影响所有实例

我做了几处修改:

  1. 创建一个新的 class NumberBoxesList 以避免全局变量并使程序的逻辑更加可见
  2. 删除 root.after 方法:此方法不应用于在用户操作后立即进行更新
  3. 使用 import tkinter as tkimport * 是不好的做法

结果:

import tkinter as tk

class NumberBox():
    def __init__(self, root,  display_number):
        self.number_label = tk.Label(root, text=display_number)
        self.number_label.pack()

    def changeNumber(self, display_number):
        self.number_label.config(text=display_number)

class NumberBoxesList():    
    def __init__(self, root,  start_number = 5):
        self.number = start_number
        self.root = root
        self.boxes = []
        tk.Button(root, text="Add Class", command= self.addBox).pack()
        tk.Button(root, text="Number UP", command=lambda: self.change_number("add")).pack()
        tk.Button(root, text="Number DOWN", command=lambda: self.change_number("subtract")).pack()

    def addBox(self):
        self.boxes.append(NumberBox(self.root,  self.number))

    def change_number(self,  operation):
        if operation == "add":
            self.number += 1
        if operation == "subtract":
            self.number -= 1
        for box in self.boxes:
            box.changeNumber(self.number)

root = tk.Tk()
boxList = NumberBoxesList(root)

for _ in range(5):
    boxList.addBox()

root.mainloop()