运行调用函数的程序时
self.getFileButton = Button(self,
text = "...",
command =
tkFileDialog.askopenfilename(mode="r+b", **self.file_opt))
我收到错误
File "C:/Documents and Settings/l/My Documents/Python/csv_GUI.py", line 33, in create_widgets
tkFileDialog.askopenfilename(mode="r+b", **self.file_opt))
AttributeError:selectFile实例没有属性'file_opt'
答案 0 :(得分:7)
您可能需要以下内容:
self.getFileButton = Button(self,
text = "...",
command = lambda: tkFileDialog.askopenfilename(mode="r+b", **self.file_opt))
问题在于,当您编写它时,askopenfilename
函数会在创建按钮时运行(而不是在单击时)。基于AttributeError,您可以在创建file_opt
映射之前创建按钮,但是,假设单击按钮时存在file_opt
属性,则应将该查找(和函数调用)推迟到适当的时间。
基本上,lambda
只会创建一个新功能:
foo = lambda x : x*x
等同于*:
def foo(x):
return x*x
以这种方式编写,很容易理解为什么我们推迟调用askopenfilename
函数,直到按钮实际被点击为止。
*在某些情况下,lambda函数的行为与常规函数不同,但我们不必担心这篇文章的目的。
答案 1 :(得分:2)
您是否确实在file_opt
方法或其他地方定义了__init__
成员?
如果问题是你要定义一个问题,但是在你完成getFileButton
之后,你能不能重新安排订单?如果没有,mgilson的解决方案是正确的。但除此之外,它更简单。
如果你在任何地方都没有file_opt
成员,那就更简单了:不要试图传递一些不存在的东西。
答案 2 :(得分:1)
我认为,一般来说,你应该避免将参数传递给 Button函数本身的回调函数(使用lambdas),它很难看,但事实并非如此 Python化。
做这样的事情:
def __init__(self, ...):
...
Tkinter.Button(self, text='...', command=self.openfile).pack(...)
...
def openfile(self):
return tkFileDialog.askopenfile(mode='r+b', **self.file_opt)
只是为了提出这个想法......