异常打印只有一个字
我有一个类,看起来像这样的部分:异常打印只有一个字
def set_new_mode(self,mode):
try:
#this will fail, since self.keithley is never initialized
print self.keithley
self.keithley.setzerocheck(on=True)
self.keithley.selectmode(mode,nplc=6)
self.keithley.setzerocheck(on=False) #keithcontrol class will
#automatically turn on zero correction when zchk is disabled
self.mode = mode
self.print_to_log('\nMode set to %s' % self.mode)
except Exception as e:
self.print_to_log('\nERROR:set_new_mode: %s' % e)
print e
由于错误处理某些测试的一部分,我已经打过电话了set_new_mode
功能,无需首先初始化类变量self.keithley
。在这种情况下,我认为print self.keithley
声明会提高AttributeError: keithgui instance has no attribute 'keithley'
。但是,print e
和self.print_to_log('\nERROR:set_new_mode: %s' % e)
指示e
仅包含单词“keithley”。
将print e
更改为print type(e)
表明e
仍具有AttributeError类型,但该变量不再包含有关该异常的任何有用信息。为什么?我该如何将e
返回到预期的形式?
编辑:这是一个水电部重现错误。 要重现错误,请启动GUI,将模式更改为VOLT以外的其他模式,然后单击更新按钮。
import Tkinter
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
class keithgui(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
#we are not initially connected to the keithley
self.connected = False
self.pauseupdate = False
#set up frames to distribute widgets
#MASTER FRAME
self.mframe = Tkinter.Frame(self,bg='green')
self.mframe.pack(side=Tkinter.TOP,fill='both',expand=True)
#LEFT AND RIGHT FRAMES
self.Lframe = Tkinter.Frame(self.mframe,bg='red',borderwidth=2,relief='raised')
self.Lframe.pack(side='left',fill='both',expand=True)
self.Rframe = Tkinter.Frame(self.mframe,bg='blue',borderwidth=2,relief='raised')
self.Rframe.pack(side='right',fill='both',expand=False)
#create the log text widget to keep track of what we did last
#also give it a scrollbar...
scrollbar = Tkinter.Scrollbar(master=self.Lframe)
scrollbar.pack(side=Tkinter.RIGHT,anchor='n')
self.logtext = Tkinter.Text(master=self.Lframe,height=3,yscrollcommand=scrollbar.set)
scrollbar.config(command=self.logtext.yview)
self.logtext.pack(side=Tkinter.TOP,anchor='w',fill='both')
#Button to update all settings
updatebutton = Tkinter.Button(master=self.Rframe,text='Update',command=self.update_all_params)
updatebutton.grid(column=2,row=0)
#Option menu & label to select mode of the Keithley
modes = ['VOLT','CHAR','CURR']
modelabel = Tkinter.Label(master=self.Rframe,text='Select Mode:')
modelabel.grid(column=0,row=2,sticky='W')
self.mode = 'VOLT'
self.modevar = Tkinter.StringVar()
self.modevar.set(self.mode)
modeselectmenu = Tkinter.OptionMenu(self.Rframe,self.modevar,*modes)
modeselectmenu.grid(column=1,row=2,sticky='W')
def print_to_log(self,text,loc=Tkinter.END):
self.logtext.insert(loc,text)
self.logtext.see(Tkinter.END)
def update_all_params(self):
self.set_refresh_rate()
if self.modevar.get() != self.mode:
self.set_new_mode(self.modevar.get())
else:
self.print_to_log('\nAlready in mode %s' % self.mode)
def set_refresh_rate(self):
try:
self.refreshrate = np.float(self.refreshrateentryvar.get())
self.print_to_log('\nRefresh rate set to %06.3fs' % self.refreshrate)
except Exception as e:
self.print_to_log('\nERROR:set_referesh_rate: %s' % e)
def set_new_mode(self,mode):
try:
print self.keithley
self.keithley.setzerocheck(on=True)
self.keithley.selectmode(mode,nplc=6)
self.keithley.setzerocheck(on=False) #keithcontrol class will
#automatically turn on zero correction when zchk is disabled
self.mode = mode
self.print_to_log('\nMode set to %s' % self.mode)
except Exception as e:
self.print_to_log('\nERROR:set_new_mode: %s' % e)
print e
print type(e)
if __name__ == "__main__":
app = keithgui(None)
app.title('Keithley GUI')
app.mainloop()
如果您修改代码:
import Tkinter as tk
class Fnord(tk.Tk):
def set_new_mode(self,mode):
try:
import pdb; pdb.set_trace()
#this will fail, since self.keithley is never initialized
print self.keithley
Fnord().set_new_mode('whatever')
,然后开始加紧通过与s
,你会看到有你的窗口上__getattr__
功能。我正在仔细查看现在导致问题的原因,但这实际上就是您的答案。
继调用堆栈,这导致我打电话self.tk = _tkinter.create
,最终导致我得到here。归根结底,这个例外发生在C领域,所以它产生了不同的AttributeError
消息。
因此,在这种情况下,似乎解决方案是首先通过'''hasattr(self,'keithley')'''检查self.keithley''是否存在,然后在没有初始化的时候引发一个AttributeError(用某种对用户有用的错误消息)。 我打算继续,并将其标记为答案,因为看起来这是由Tk的实现而非我的代码引起的,所以解决方法就像我上面发布的那样。 – Nick
你可以随时在*你的*代码中添加一个'getattr',然后让它穿透堆栈。但是,为什么不在开始时将'keithley'设置为合理的呢?如果可能,应避免[时间耦合](http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling/)。 –
'keithley'实际上是一个包含python机器的类,通过RS232与仪器对话。 GUI的目的是显示/处理从吉时利绘制的数据。问题是,有时候有多个keithleys连接到一台机器,并且GUI想要连接到用户在连接时设置的特定连接(所以不能提前定义)。我可以做一些像'''self.keithley = None''',并检查'''如果self.keithley == None:raise ...''',但与检查它是否基本相同存在?这是你如何建议实施它? – Nick
你能提供最少的代码来重现问题吗,所以我们可以看到我们是否看到同样的问题? – depperm
您可能想查看'logging'模块 - 特别是'logging.exception()'是非常有用的 –
我不能再现这个,我得到'ERROR:set_new_mode:Fnord实例没有属性'keithley' Fnord实例没有属性'keithley'' –