2

私はPythonでプロシージャを作成しています。このプロシージャは、基本的なレベルでモーターコントローラーと通信します。コントローラがエラーが発生したことを示すフラグをスローする可能性があります。私はこれらのエラーを最もよく処理する方法を見つけようとしています。

以下の例では、温度障害、電流制限障害、および電圧障害の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.

しかし、それはどういうわけか、私が本当に理解していない用語を使用するのは間違っているか、非Python的であるように思われます。これには本当に何か問題がありますか?おかげで、私はCS専攻ではなく、1982年以来プログラミングクラスを受講していないことを覚えておいてください。

4

4 に答える 4

2

私のアプローチは、その価値のために、例外の小さな階層を定義することです。

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

次に、エラーが発生した場合は、APIがそれらのいずれかをスローすることを確認してください。API自体が、基盤となるモーターAPIからの例外をキャッチする必要がある場合は、その例外を独自の例外の1つでラップします。

理論的根拠:

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

  • あなたはより良いものを見つけました。
  • モックアップされたモーターAPIを使用してテストを実行したいとします。

また、(フラグではなく)例外は、他のPythonAPIの動作とより一貫性があります。

于 2010-12-29T21:45:40.740 に答える
0

これらのケースは例外/失敗のシナリオのように思われるため、この時点で処理したいすべての異なる例外について、多くの例外句を含む例外を選択します。

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

これをうまく処理するための「正しい」方法であるかどうかを知る限り、両方のソリューションが機能する場合は、両方とも正しいです!

私が十分に明確であったことを願っています...;-)

于 2010-12-29T21:33:06.613 に答える
0

どちらのアプローチでも問題はありません。個人的に、私は試してみるのが好きです-1つを除いて、しかしそれはただの好みです。

于 2010-12-29T21:36:27.913 に答える
0

正しい方法はありますか

はい。

それとも主観的ですか?

いいえ。

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

まず、独自の例外としてCapitalLettersを使用してください

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

次に、エラー検出を残りの処理から分離します。

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

第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

于 2010-12-29T21:37:19.113 に答える