从类中返回值 Python
编辑
我之前问过这个问题,得到了不错的反馈,但我觉得我的问题并没有真正得到解答。我正在用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.displayspace
为 self.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 个回答
一般来说,你不是在不同的类之间传递值,而是在这些类的实例之间传递值。随时可能有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
实例之间可能有很多不同的关系,哪种关系合适完全取决于Foo
和Bar
实际代表的是什么。这就是对象建模背后的代码理念:你的对象代表某种事物,而这些事物之间的关系反映在这些对象之间的关系中。