这是How do you programmatically set an attribute?的后续问题。
我看到如何使用setattr(x,attr,value)设置属性值。
我如何在attr上调用方法?
例如,我想创建和设置与字典相对应的Tkinter Entry对象的值,其中键是属性,值是要分配给属性的值。
我的蛮力方法有效:
from tkinter import Tk, Button, filedialog, Label, Frame, BOTH, Entry, END, StringVar
class Example(Frame):
def __init__(self, master=None):
"""Initialize UI and set default values."""
# https://stackoverflow.com/questions/285061/how-do-you-programmatically-set-an-attribute.
Frame.__init__(self, master)
self.master = master
myDict = {'a': 'String A', 'b': 'String B', 'c': 'String C'}
self.a = StringVar()
self.a.set(myDict['a'])
self.aEntry = Entry(self, textvariable=self.a)
self.aEntry.grid(row=0, column=1)
self.b = StringVar()
self.b.set(myDict['b'])
self.bEntry = Entry(self, textvariable=self.b)
self.bEntry.grid(row=1, column=1)
self.c = StringVar()
self.c.set(myDict['c'])
self.cEntry = Entry(self, textvariable=self.c)
self.cEntry.grid(row=2, column=1)
self.pack(fill=BOTH, expand=1)
root = Tk()
app = Example(root)
root.mainloop()
循环方法看起来像这样:
from tkinter import Tk, Button, filedialog, Label, Frame, BOTH, Entry, END, StringVar
class Example(Frame):
def __init__(self, master=None):
"""Initialize UI and set default values."""
# https://stackoverflow.com/questions/285061/how-do-you-programmatically-set-an-attribute.
Frame.__init__(self, master)
self.master = master
myDict = {'a': 'String A', 'b': 'String B', 'c': 'String C'}
rowCount = 0
for key, value in myDict.items():
setattr(self, key, StringVar()) # Works
# self.a.set('String A')
self.key.set(value) # Does not work
# self.aEntry = Entry(self, textvariable=self.a)
setattr(self, key + 'Entry', Entry(self, textvariable=???)) # Does not work
# self.aEntry.grid(row=0, column=1)
self.key + 'Entry'.grid(row=rowCount, column=1) # Does not work
rowCount += 1
self.pack(fill=BOTH, expand=1)
root = Tk()
app = Example(root)
root.mainloop()
如何重写标有“#不起作用”的行,以便循环工作?
这不仅仅是一个Tkinter问题。我可以想到其他情况,其中一个人可能想要在属性上调用一个方法,该方法的名称被赋给一个字符串变量。我很感激教练。
答案 0 :(得分:1)
我不会为此使用单独的属性;我使用dict
个关联的Entry
和StringVar
对象。
getattr
和setattr
有自己的位置,但不能取代合理使用dict
。
class Example(Frame):
def __init__(self, master=None):
"""Initialize UI and set default values."""
# https://stackoverflow.com/questions/285061/how-do-you-programmatically-set-an-attribute.
Frame.__init__(self, master)
self.master = master
myDict = {'a': 'String A', 'b': 'String B', 'c': 'String C'}
self.entries = {}
for rowCount, (key, value) in enumerate(myDict.items()):
sv = StringVar()
sv.set(value)
e = Entry(self, textvariable=sv)
e.grid(row=rowCount, column=1)
self.entries[key] = (e, sv)
self.pack(fill=BOTH, expand=1)
答案 1 :(得分:1)
要完全回答您提出的问题,您可以使用getattr
获取对该属性的引用,此时您可以将其视为真实属性。
setattr(self, key, StringVar())
var = getattr(self, key)
var.set(...)
然而,这是一个坏主意。如果您使用字典来跟踪动态内容,您的代码将更容易编写,理解和修改。
例如:
rowCount = 0
self.vars = {}
self.entries = {}
for key, value in myDict.items():
self.vars[key] = StringVar()
self.vars[key].set(value)
self.entries[key] = Entry(self, textvariable=self.vars[key])
self.entries[key].grid(row=rowCount, column=1)
rowCount += 1