2014-10-08 40 views
0

我認爲這將通過一個例子很容易地演示,但問題是一個普遍的問題。假設我正在使用像PyVISA這樣的庫,它將GPIB設備與我的程序連接起來。我已成立了每一器具的Python類,所以對電源,我可能有這樣的事情:使用連接的硬件進行編程

import visa 

class PowerSupply: 
    def __init__(self): 
     rm = visa.ResourceManager() 
     self.ps = rm.open_resource('GPIB0::12::INSTR') 
    def getVoltage(self): 
     return self.ps.ask('VOLT?') 
    def setVoltage(self,v): 
     self.ps.write('VOLT '+str(v)) 
    ... 

ps = PowerSupply() 
ps.setVoltage(10) 

不幸的是,該rm.open_resource功能可能無法正常工作,或者可能會返回None機會一個設備不存在於該地址(在我的代碼中,我實際上是編寫了一個功能來代替它)。我的問題是:編碼類似PowerSupply的最佳做法是什麼?可以在每種方法中寫入例外,以測試self.ps是否存在/不是None,但似乎必須有更好的方法。在那兒?!

+1

肯定'__init__'在這種情況下應該失敗,拋出一個錯誤? – jonrsharpe 2014-10-08 18:27:47

+0

來進一步jon的評論...它應該是調用者的工作來管理依賴關係 'try:ps = PowerSupply();除了:do_something_else()'...和init應該肯定會發現一個關於沒有powersupply發現的錯誤 – 2014-10-08 18:30:24

+1

@jonrsharpe:問題說'open_resource'「可能會返回'None'」。所以不,'__init__'在這種情況下不會失敗。但是解決辦法是在這種情況下使其失敗。添加一個'if not self.ps:raise SomeException('打開資源失敗')'或類似的東西。 – abarnert 2014-10-08 19:36:11

回答

2

可以在每個方法中寫入例外,以測試self.ps是否存在/不是None,但似乎必須有更好的方法。在那兒?!

是。您編寫代碼的方式,如果self.ps永遠是None,那麼它將從一開始就是None,並且永不再改變。因此,而不是在每一個方法的測試,只是測試它一次:

def __init__(self): 
    rm = visa.ResourceManager() 
    self.ps = rm.open_resource('GPIB0::12::INSTR') 
    if self.ps is None: 
     raise PowerSupplyException('Unable to open resource GPIB0::12::INSTR') 

現在,任何代碼結構一個PowerSupply必須或者處理該異常或準備進行傳播,但你的問題暗示無論如何,open_resource可能會引發異常,所以不會成爲問題。此外,這似乎是處理它的正確位置 - 在程序的頂層,無論您是在創建一個PowerSupply以響應某些GUI或CLI或網絡命令,這就是您準備處理無法處理的地方創建它,對吧?

而任何使用已經構建的PowerSupply的代碼都沒有什麼可擔心的。你知道self.ps is not None或者你不能從構造函數中獲取對象。