Python 只打印一个字的例外

Python 只打印一个字的例外,python,exception,Python,Exception,我有一个类的一部分看起来像这样: 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) sel

我有一个类的一部分看起来像这样:

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\u new\u mode
函数,而不首先初始化类变量
self.keithley
。在本例中,我希望
print self.keithley
语句会引发
AttributeError:keithgui实例没有属性“keithley”
。但是,
print e
self.print\u to\u log('\n错误:设置新模式:%s'%e)
表示
e
仅包含单词“keithley”

print e
更改为
print type(e)
会显示
e
仍然具有类型AttributeError,但变量不再包含有关异常的任何有用信息。为什么?如何将
e
返回到预期的形式

编辑:这里有一个MEW来重现错误要再现错误,请启动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
,您将看到窗口上有一个
\uu getattr\uu
函数。我现在正在查看问题的原因,但这实际上是你的答案



在调用堆栈之后,它引导我调用
self.tk=\u tkinter.create
,最终使我得到了一个调用。归根结底,这归结为异常发生在C-territory中,因此它产生了一个不同的
AttributeError
消息。

您能否提供最少的代码来重现问题,这样我们就可以看到是否出现了相同的问题?您可能需要查看
日志记录
模块,尤其是
日志记录.exception()
非常有用,我无法重现,我得到了
错误:设置新模式:Fnord实例没有属性'keithley'Fnord实例没有属性'keithley'
您的类中是否有
\uGetAttribute\uuuuuu
?@WayneWerner-打印到日志函数实际上是一个在GUI中打印到Tkinter文本日志的函数(这就是这个类实际告诉我们的)。但我同意日志模块很棒!因此在本例中,解决方案似乎是首先通过
hasattr(self,'keithley')
检查
self.keithley
的存在,然后如果它还没有初始化,则引发AttributeError(为用户提供一些有用的错误消息)。我将继续并将其标记为答案,因为这似乎是由Tk的实现引起的,而不是我的代码,所以解决方法与我在上面发布的类似。您可以始终在代码中添加
getattr
,然后让它渗透到堆栈中。但是,为什么不将
keithley
设置为somet“keithley”实际上是一个类,它包含python通过RS232与仪器对话的机制。GUI的目的是显示/操作从keithley提取的数据。问题是,有时有多个keithley连接到一台机器,GUInts连接到用户在连接时设置的特定nts(因此无法提前定义)。我可以做一些类似设置self.keithley=None的事情,如果self.keithley=None:raise…,则检查
,但这与检查它是否存在基本相同吗?这就是您建议的实现方式吗?如果他们没有连接到特定的keith,为什么您一开始就允许他们更改模式ley?看起来你想检查keithley's的可用性,要么a)连接到你找到的第一个,要么b)什么都不连接,等待他们连接到一个。但是,在它们连接之前,任何类型的配置按钮或条目都应该被禁用。