运行Python时的AttributeError
运行进行函数调用的程序时运行Python时的AttributeError,python,Python,运行进行函数调用的程序时 self.getFileButton = Button(self, text = "...", command = tkFileDialog.askopenfilename(mode="r+b", **self.file_opt)) 我得到了错误 File "C:/Documents and Setti
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\u opt”您可能需要以下内容:
self.getFileButton = Button(self,
text = "...",
command = lambda: tkFileDialog.askopenfilename(mode="r+b", **self.file_opt))
问题是,在编写时,askopenfilename
函数在创建按钮时运行(而不是在单击时)。根据AttributeError,在创建文件选项
映射之前创建按钮,但是,假设单击按钮时存在文件选项
属性,则应将查找(和函数调用)推迟到适当的时间
基本上,lambda
只是创建了一个新函数:
foo = lambda x : x*x
相当于:
def foo(x):
return x*x
通过这种方式编写,很容易理解为什么我们推迟调用askopenfilename
函数,直到按钮实际被单击为止
*在一些情况下,lambda函数的行为与常规函数不同,但在本文中,我们不必担心这些情况。我认为,一般来说,您应该避免将参数传递给 在按钮函数本身中的回调函数(使用lambdas),它是丑陋的,它不是 蟒蛇的 改为这样做:
def __init__(self, ...):
...
Tkinter.Button(self, text='...', command=self.openfile).pack(...)
...
def openfile(self):
return tkFileDialog.askopenfile(mode='r+b', **self.file_opt)
只是想说明一下…您是否真的在中定义了
文件\u opt
成员,例如,您的\u init\u
方法或其他地方
如果问题是您正在定义一个,但直到完成getFileButton
之后,您才能重新排列顺序吗?如果不是的话,米吉尔森的解决方案就是正确的。但除此之外,它要简单得多
如果你在任何地方都没有
文件\u opt
成员,那就更简单了:不要试图传递不存在的东西。+1关于lambda的更多解释,而不是像在这里的答案中经常发生的那样让它放在那里。事实证明这不是他的(直接)问题,但正如我上面所说的,看起来这很可能是他15分钟后的下一个问题,所以先回答+1。@abarnert--我也解决了直接的问题:“根据AttributeError,你在创建文件映射之前创建按钮”,但我没有像你那样在我的回答中突出显示,因为我假设映射是在附近创建的。根据其他一些评论,这个假设似乎是不正确的。是的,听起来他根本没有我所怀疑的文件。(这就提出了他从何处复制和粘贴此代码的问题…)重新排列顺序可能会解决此问题,但每当您尝试单击按钮时,都会出现“字符串不可调用”错误。@mgilson:没错,尽管这是一个单独的问题。如果他实际上根本没有file\u opt
成员(这似乎很有可能),那么延迟函数调用只会让他认为自己解决了问题,直到他每次单击按钮时都会出现相同的错误。最好马上找到这两个问题。结果是我需要一个文件,我只是被函数中的参数弄糊涂了,以为它已经在其中一个库中定义了。@user1876508:好的,请记住,解决了这个问题后,接下来很可能会看到mgilson的问题,他已经告诉了你如何修复它。我的下一个问题是,我如何作为字符串变量访问文件位置?我想更新标签中的文本以显示此信息。不可否认,我没有花太多时间处理其他人的python代码(除了很多答案)。然而,如果这不是lambda
的候选项,我真的不知道是什么。你为什么说lambda
在这里是“非音速”呢?定义一个额外的函数会使您的名称空间变得混乱(这不太可能是一件大事)。另外,您的openfile
函数不应接受self
参数。它将从闭包中获得self
,并且按钮“command”没有收到任何参数。@mgilson:看起来他正在这个函数中本地定义新函数,因此名称空间问题不是问题。但你仍然是对的,这似乎是一个地方,甚至Guido可能会使用lambda
——事实上,大多数TkInter示例代码要么使用绑定方法,要么使用lambda
s。当然,这是lambda
的一个很好的候选者,但是lambda
让我几乎看不懂这行代码。我不是lambda的超级粉丝(我也不是一个人!),仅此而已。我是导入此;)的粉丝。很抱歉,对代码进行了编辑以使其更清晰(我希望:P)。@abarnert--是的,这就是为什么我说名称空间参数不是什么大问题。当然,您可能会在全局名称空间中隐藏一些东西,但归根结底,这些东西只是一个麻烦——不是一个真正的问题(这就是为什么我说它“不太可能是一个大问题”)。我的主要观点是,这是一个使用lambda
的经典地方,我不知道为什么在这个答案中它被描述为“丑陋”和“不pythonic”。@NicolaLamacchia——如果你站在队伍太长的立场上争论,我可以理解(并同意你)。它可能超过了PEP-8推荐的72个字符(或者不管行的长度是多少)。但是,在这种情况下,我不认为问题在于lambda
本身。如果以更简单的名称导入该函数,问题就会消失。我个人认为lambda
是一个非常有用的工具。考虑有50个按钮,每个按钮都有自己的命令。使用lambda
可以快速地使代码比显式函数好得多。您是否真的有file\u opt
成员?