2010-12-29 26 views
2

私はPythonで手続きを書いています。それは基本レベルではモーターコントローラと通信します。コントローラーは、エラーが発生したことを示すフラグをスローすることができます。私はこれらのエラーを最良に処理する方法を理解しようとしています。外部例外を処理するためのPythonのベストプラクティス(raiseを使用しますか?)

以下の例では、温度エラー、電流制限フォルト、および電圧フォルトの3つのエラーが考えられます。私はそれらを別々に扱った。正しい方法があるのか​​、それとも主観的なのでしょうか?

class motor_fault(Exception): 
    def __init__(self,error): 
     motor.move_at = 0 #Stop motor 
     self.error = error 
    def __str__(self): 
     return repr(self.value) 

motor.velocity_limit = motor.slow 
motor.velocity_limit_enable = True 
try: 
    motor.move_to_absolute = motor.instrument_pos 
    while motor.in_position == 0: 
     if motor.current_limit == 1: 
      motor.move_at = 0 #Stop motor 
      print('Motor current error') 
      break 
     if motor.temp_fault == 1: raise motor_fault('Temperature Fault') 
     if motor.voltage_fault == 1: raise voltage_fault: 
     time.sleep(0.5) 
    else: 
     print('reached desired instrument position with no faults') 
except motor_temp_fault as e: 
    #Not sure what I'd do here... 
    print('My exception occurred, value:', e.error) 
    pass 
except: 
    motor.move_at = 0 #Stop motor just in case 
    print(' some other fault, probably voltage') 
else: 
    print (' this is only printed if there were no errors') 
finally: 
    print ('this is printed regardless of how the try exits') 

try:全体を削除する方がはるかに簡単です。 whileループにフラグを設定してブレークするだけです。ループの後、フラグを見て、whileループが正常に終了したかどうかを確認します。

fault = False 
while motor.in_position == 0: 
    if motor.current_limit == 1: 
     fault = 'Motor current error' 
     break 
    if motor.temp_fault == 1: 
     fault = 'Motor temperature error' 
     break 
    if motor.voltage_fault == 1: 
     fault = 'Motor voltage error' 
     break 
    time.sleep(0.5) 
else: 
    print('reached waterline with no faults') 
if fault: 
    motor.move_at = 0 #Stop motor 
    print(fault) 
    # Now look at the fault string to determine the next course of action. 

しかし、どういうわけか、私は本当に理解していない用語を使用することが間違っているか、非ニシキヘビ思われます。本当にこれに間違っていますか? 私はCS専攻ではなく、1982年以来プログラミングクラスを受講していないことを覚えておいてください。

+0

MotorFaultクラスを定義し、tryとexceptを使用しているようですが、BrianとS.Lottsがその答えに示唆しているのは方法です。 関心のある人のためにもう少し背景を与える。モータークラスは私のために他の誰かによって書かれましたが、私はそれを変更することができます。モーターのメソッドは、実際にはモーターコントローラードライバーに送信されるJSON-RPCメッセージに変換されます。これにより、モーターオブジェクトは非常に簡単なメッセージハンドラーになります。このため、モーターの状態チェックは実際にモーターオブジェクトに入るべきではありません。私は別のオブジェクトでそれをラップすることができると思いますが、私はcheck()関数の考え方が好きです。 – RyanN

+0

...モータコントローラドライバ(Javaで書かれています)は、値が変わるたびにJSON-RPCを介してステータス更新を私のPythonプログラムに送ります。あなたが疑うかもしれないように、これらのメッセージを待ち受けて、モーターの属性を更新する別のスレッドがあります。 私が書いているコードは、マイクロコントローラで動作するBASICのシンプルなバージョンのポートです。コードは、プログラミングの知識が多少限られている人が、機能ではないにしても動作を変更できるように、十分に単純である必要があります。 – RyanN

+0

... 私は、PythonがJavaよりも適切であると主張する必要があったので、コードの手続き部分をできるだけシンプルに保つことを試みています。 – RyanN

答えて

2

私のアプローチは、何が価値があるのは、例外の小さな階層を定義することであろうために、言う:

class MotorFaultError(Exception) # top level exception 
class MotorTempFault(MotorFaultError) 
class MotorVoltageFault(MotorFaultError) 
# etc 

その後は、何らかのエラーで、あなたのAPIは、これらのいずれかをスローしていることを確認します。 API自体が、基礎となるモーターAPIから例外をキャッチしなければならない場合は、独自の例外の1つでその例外をラップします。

理由:

独自の例外階層はAPIの一部であり、基礎となるモータAPIの仕様から、呼び出し元のコードを分離するのに役立ちます。定義された一連の例外をスローすることにより、モーターAPIの例外をバブルアップさせるのではなく、基礎となるAPIをさらに隠すことになります。そうすることで、次のような理由で、別のモータAPIを簡単に削除することができます。

  • あなたは良いものを見つけました。
  • モックアップされたモータAPIでいくつかのテストを行いたいとします。

また、(フラグではなく)例外は、他のPython APIの動作と一貫しています。

0

私はあなたが扱いたいすべての例外これらのケースは例外的/失敗シナリオのように見えるため、この点が重要です。

これらのシナリオを表現するためにフラグを使用しません。これは、このユースケースの外では役に立たない/関連すると思われないフィールドをモーターに追加するためです。

この井戸を処理するのが正しい方法であるかどうかを知る限り、両方の解決策が有効な場合はどちらも正しいです!私はどちらかのアプローチに何か問題が表示されていない、私は十分に明確だった

希望... ;-)

0

。個人的には、私はtry-except oneを好むが、それは単なる好みだ。

1

正しい方法ははいあります。

またはそれは主観的ですか?

raiseステートメントを使用します。

まず、あなたの残りの処理からエラー検出を分離し、第二

class Motor_Fault(Exception): pass 
class Temperature_Fault(Motor_Fault): pass 
class Voltage_Fault(Motor_Fault): pass 
class Current_Fault(Motor_Fault): pass 

独自の例外をCapitalLettersを使用してください。

第3に、例外クラスで何もしないでください。アプリケーションでモータ停止事業を処理します。

第4に、モータステータスチェックでは、アプリケーションのモータループにではないは含まれません。これは、すべてmotor.move_to_absoluteを実装するメソッド関数の一部です。

if motor.current_limit == 1: raise Current_Fault() 
    if motor.temp_fault == 1: raise Temperature_Fault() 
    if motor.voltage_fault == 1: raise Voltage_Fault() 

第5に、アプリケーションのループは次のようになります。

motor.velocity_limit = motor.slow 
motor.velocity_limit_enable = True 
try: 
    motor.move_to_absolute = motor.instrument_pos 
    while motor.in_position == 0: 
     time.sleep(0.5) 
    print('reached desired instrument position with no faults') 
except Motor_Fault, e: 
    motor.move_at = 0 #Stop motor 
    print(fault) 

モータはそれ自身の例外を発生させる必要があります。何らかの理由でそれができない場合は、ステータスチェックをしてモータを「ラップ」することができます。これは理想的ではありません。なぜなら、モーターはそれ自身の例外を発生させるべきだからです。

def check(): 
    if motor.current_limit == 1: raise Current_Fault() 
    if motor.temp_fault == 1: raise Temperature_Fault() 
    if motor.voltage_fault == 1: raise Voltage_Fault() 

sleepの直前にこの関数を呼び出します。

+1

-1。これは間違っています。正しい方法はなく、実際は主観的です。いくつかの方法は他の方法より優れています。しかし、常に例外を使用すると言うのは間違っています。 – Falmarri

+0

@Falmarri:具体的な反例がありますか?あなたの主張を明らかにする具体的な何か? –

+1

私の主張はそれが主観的であるということです。どうすれば具体的な証拠を得ることができますか?それはコーディングスタイルです。これはモーターコントローラであることから、例外処理は高価であるため、私はほとんどの場合、状態フラグと一緒に行くと言います。しかし、私はプロジェクト全体がどのように見えているかわからないので、私は言うことができず、あなたもどちらもできません。 – Falmarri

関連する問題