我刚开始学习Python,我遇到了这个问题。我想从方法内部设置变量,但变量在方法之外。
该方法由按钮激活。然后我想从我按下另一个按钮时设置的变量中获取值。问题是我从方法内部放入变量的值不会保留。我该如何解决这个问题?
代码在下面。 currentMovie
是我试图改变的变量。当我用方法UpdateText()
按下按钮时,它打印出一个像它应该的随机数。但是当我按下激活UpdateWatched()
的按钮时,它会输出0.所以我假设变量永远不会被设置。
import random
from tkinter import *
currentMovie = 0
def UpdateText():
currentMovie = random.randint(0, 100)
print(currentMovie)
def UpdateWatched():
print(currentMovie)
root = Tk()
root.title("MovieSelector9000")
root.geometry("900x600")
app = Frame(root)
app.grid()
canvas = Canvas(app, width = 300, height = 75)
canvas.pack(side = "left")
button1 = Button(canvas, text = "SetRandomMovie", command = UpdateText)
button2 = Button(canvas, text = "GetRandomMovie", command = UpdateWatched)
button1.pack(anchor = NW, side = "left")
button2.pack(anchor = NW, side = "left")
root.mainloop()
答案 0 :(得分:5)
这是一个简单的(python 2.x)示例,说明如何1 不使用全局变量,2使用(简单)域模型类。
重点是:您应该首先独立于用户界面设计域模型,然后编写调用域模型的用户界面代码。在这种情况下,您的UI是一个Tkinter GUI,但相同的域模型应该能够使用命令行UI,Web UI或其他任何内容。
注意:对于python 3.x,将Tkinter
替换为tkinter
(小写),您可以删除object
的{{1}}基类。
Model
答案 1 :(得分:2)
使用global
修改函数外的变量:
def UpdateText():
global currentMovie
currentMovie = random.randint(0, 100)
print(currentMovie)
但是,请勿使用global
。通常是code smell。
答案 2 :(得分:1)
这是一个简单但肮脏的解决方案:使用可变变量。
代替
currentMovie = 0
def UpdateText():
currentMovie = random.randint(0, 100)
print(currentMovie)
您可以为currentMovie使用一个单元格列表,并将其作为(默认)参数传递给UpdateText():
currentMovie = [0]
def UpdateText(cM=currentMovie): # The default value will 'bind' currentMovie to this argument
cM[0] = random.randint(0, 100) # This will change the *contents* of the variable
print(cM[0]) # I used a different name for the parameter to distinguish the two
UpdateText() # Calls UpdateText, updating the contents of currentMovie with a random number
请注意,将currentMovie
本身(而不是其内容)设置为新值(甚至使用新列表)也会导致UpdateText()
停止更新currentMovie
,除非def
块再次运行。
currentMovie = [0]
def UpdateText(cM=currentMovie): # The default value will 'bind' currentMovie to this argument
cM[0] = random.randint(0, 100) # This will change the *contents* of the list
print(cM[0]) # I used a different name for the parameter to distinguish the two
currentMovie = 3 # UpdateText() will no longer affect this variable at all
# This will thus not throw an error, since it's modifying the 'old' currentMovie list:
UpdateText() # The contents of this list can also no longer be accessed
如果您要构建又快又脏又不想构建类的东西,那么这更是一个方便的技巧;我发现Python非常适合这类事情,因此尽管有其他答案,我仍然认为值得分享。
不过,出于更严肃的目的,几乎可以肯定,像bruno's answer中那样创建类会更好。