2016-07-26 14 views
1

1ワードのみ:エラー処理のいくつかのテストの一環として、私が最初にself.keithleyクラスは、変数初期化せずにset_new_mode関数を呼び出して試してみた例外印刷私はこのようになりますクラスの一部を持っている

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 

。この場合、print self.keithleyステートメントはAttributeError: keithgui instance has no attribute 'keithley'となることが予想されます。しかし、print eself.print_to_log('\nERROR:set_new_mode: %s' % e)は、eには単語 "keithley"のみが含まれていることを示しています。

print eprint 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() 
+0

問題を再現するための最小限のコードを提供できるので、同じ問題があるかどうかを確認できますか? – depperm

+0

'logging'モジュールをチェックアウトしたいと思うかもしれません - 特に' logging.exception() 'は非常に便利です –

+0

私はこれを再現できません、' ERROR:set_new_mode:Fnordインスタンスに属性がありません 'keithley' Fnordインスタンス'keithley'属性がありません –

答えて

1

:その後、

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__機能があることがわかります。私は今何が問題を引き起こしているか見ることを探していますが、それは効果的にあなたの答えになるでしょう。コールスタックに続き


、それは最終的に私がhereを得る主導コールself.tk = _tkinter.create、に私を導きました。結局のところ、このことは、例外がC領域で起こっていることであるため、異なるAttributeErrorメッセージを生成しています。

+0

この場合、解決策は最初に '' '' 'hasattr(self、 'keithley')' ''を介して '' self.keithley''の存在をチェックし、まだ初期化されていなければAttributeErrorを送出します。ユーザーにとって有用なエラーメッセージ)。 これは私のコードではなくTkの実装に起因すると思われるので、これを答えとしてマークします。そのため、上記のような回避策があります。 – Nick

+1

*あなたの*コードに 'getattr'を追加してから、スタックに浸透させることができます。しかし、初めに「キートラック」を妥当なものにするだけではいかがですか?可能であれば、[一時的結合](http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling/)は避けてください。 –

+0

'keithley'は、実際には、PythonがRS232経由で楽器と会話するための機械を含むクラスです。 GUIの目的は、キースライスから引き出されたデータを表示/操作することです。問題は、マシンに複数のキースリーが接続されていることがあり、GUIが接続時にユーザーが設定した特定のキーに接続しようとしていることです(事前に定義することはできません)。私は '' 'self.keithley = None'''をセットし、' 'self.keithley == None:raise ...' ''をチェックするような何かをすることができます。存在するか?それを実装することをお勧めしますか? – Nick

関連する問題