从类中返回值 Python

0 投票
1 回答
2140 浏览
提问于 2025-04-18 16:37

编辑

我之前问过这个问题,得到了不错的反馈,但我觉得我的问题并没有真正得到解答。我正在用Python做一个小程序,练习制作图形界面(GUI),现在在按钮命令上遇到了一点小问题。

#This is the temperature menu:
def temperM(self, *args):
    self.clearscreen(self.frame)
    self.frame2 = Frame(self.root)
    self.frame2.grid(column = 0, row = 0)


    self.firstunit = StringVar()
    self.secondunit = StringVar()

    self.entryspace = IntVar()
    self.displayspace = IntVar()

    #Create back button

    #This is the part that needs to be fixed

    self.back = Button(self.frame2, text = "< Back",
     command = lambda: self.redo(self.frame2))
    self.back.grid(column = 1, row = 3)

    self.label = Label(self.frame2, text = "Convert from: ")
    self.label.grid(column = 1, row = 1, padx = 4)

    #Create the check boxes

    self.celsius = Checkbutton(self.frame2, text = "Celsius",
     variable = self.firstunit, onvalue = 'celsius')
    self.celsius.grid(column = 2, row = 1)

    self.fahrenheit = Checkbutton(self.frame2, text = "Fahrenheit",
     variable = self.secondunit, onvalue = 'fahrenheit')
    self.fahrenheit.grid(column = 3, row = 2)

    #Create entry space to recieve text


    #This is where the problem starts.
    self.entry = Entry(self.frame2, width = 7,
     textvariable = self.entryspace)
    self.entry.grid(column = 3, row = 3)

    self.compute = Calculate(self.entryspace.get())

    self.button = Button(self.frame2, text = "Calculate",
     command = lambda: self.displayspace.set(self.compute.celtoFah()))
    self.button.grid(column = 3, row = 4)

    self.display = Label(self.frame2, textvariable = self.displayspace)
    self.display.grid(column = 2, row = 2)

我在一个叫做 Menu 的类里面有一个函数 def __init__(self, root),这个函数用来创建各种菜单选项。

class Calculate:

    def __init__(self, number):
        self.number = number

    def celtoFah(self):
        try:
            self.temp = Temperature()
            self.number = float(self.number)
            return self.temp.C2F(self.number)
        except ValueError:
            pass

我还有一个类,用来保存代码中会用到的各种计算。

我现在遇到的问题是我的按钮命令 command = lambda: self.displayspace.set(self.compute.celtoFah())。当我运行代码并点击“计算”按钮时,这个命令 self.displayspace.set() 并没有把 self.displayspace 设置为我认为应该返回的值。相反,它返回并设置 self.displayspaceself.entryspace.get() 原本的值,没有任何修改,这个值分别是32和0。这让我觉得 self.compute = Calulate(self.entryspace.get()) 这一行在我输入新值时没有更新,所以 self.entryspace 并没有得到新值,而是保留了最初由 IntVar() 设置的值。我在代码中是不是做错了什么,导致 self.entryspace 没有更新新值?起初我把它设置为 StringVar(),这样在 celtoFah 中会转换为浮点数,但我遇到了值错误(ValueError),因为即使用户输入了值,它还是接收到了一个空字符串。我真的想把所有的计算放在一个单独的类里,因为最终版本会有20多个计算,但我应该把这些命令移到 class Menu 里,还是有其他方法可以在保持单独类的情况下做到这一点?如果你需要查看我的完整代码,这里有一个链接到我的GitHub:https://github.com/Flameancer/Unit-Conversion-Program-in-Python

1 个回答

2

一般来说,你不是在不同的之间传递值,而是在这些类的实例之间传递值。随时可能有0个、1个或30个不同的Foo实例;那么一个Bar实例怎么知道你想要的是哪一个呢?

第一个问题是,谁在调用那个Bar里的something方法?不管是谁,他手里都有那个值。也许应该是Foo实例来调用这个方法。

为了实现这一点,foo实例需要知道一个bar实例。也许你想在构造函数里创建一个:

class Foo:
    def __init__(self, argument):
        # ...
        self.bar = Bar(42)
        # ...

…这样你就可以像使用其他成员一样使用它:

    def function(self, *args):
        # ...
        randomness = self.bar.something()
        self.displayfield.set(randomness)
        # ...

或者也许你已经在某个地方构造了一个实例,只是想把它作为构造函数传递给Foo实例:

class Foo:
    def __init__(self, argument, bar):
        # ...
        self.bar = bar
        # ...

bar = Bar(42)
foo = Foo(23, bar)

或者你可能想在每次调用function方法时都在本地构造一个新的Bar实例。又或者你想要一个全局的Bar实例,让所有人共享,不管你有多少个Foo实例。或者…

正如你所看到的,Foo实例和Bar实例之间可能有很多不同的关系,哪种关系合适完全取决于FooBar实际代表的是什么。这就是对象建模背后的代码理念:你的对象代表某种事物,而这些事物之间的关系反映在这些对象之间的关系中。

撰写回答