我正在用Python编写一个程序,它的基本级别与电机控制器通信。控制器可以抛出表示发生错误的标志。我想弄清楚如何最好地处理这些错误。
在下面的示例中,有三种可能的错误,温度故障,电流限制故障和电压故障。我对他们的处理方式不同了。有正确的方法还是主观的?
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.
但是,使用我并不真正理解的术语,似乎有些错误或非pythonic。这有什么不妥吗? 谢谢,请记住,我不是CS专业,自1982年以来我没有参加过编程课程。
答案 0 :(得分:2)
我的方法,就是它的价值,是定义一个小的异常层次结构,比如说:
class MotorFaultError(Exception) # top level exception
class MotorTempFault(MotorFaultError)
class MotorVoltageFault(MotorFaultError)
# etc
然后,在出现任何错误时,请确保您的API会抛出其中一个错误。如果您的API本身必须从基础电机API捕获异常,请将该异常包装在您自己的异常中。
理由:
您自己的异常层次结构是API的一部分,用于将调用代码与基础电机API的细节隔离开来。通过抛出一组定义的异常,而不是允许电机API的异常冒泡,您进一步隐藏了底层API。这样做可以更容易地放弃另一个电机API,无论出于何种原因,包括:
此外,异常(而不是标志)与其他Python API的行为方式更加一致。
答案 1 :(得分:1)
有没有正确的方法
是
还是主观的?
没有
使用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
其次,将错误检测与其余处理分开。
第三,不要在异常类中做任何事情。在您的应用程序中处理电机停止业务。
第四,电机状态检查不属于应用程序的电机回路。这是实现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()
第五,你的应用程序循环应该是这样的。
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
之前调用此函数。
答案 2 :(得分:0)
我会针对你想要处理的所有不同异常的许多例外条款进行例外处理,因为这些情况似乎是异常/失败情况。
我不会使用标志来表示这些场景,因为它会向电机添加更多字段,这些字段在此用例之外似乎没有用处/相关。
至于知道这是否是“正确”处理这种方法的方法,如果两种解决方案都有效,那么它们都是正确的!
希望我足够清楚......; - )
答案 3 :(得分:0)
我认为这两种方法都没有错。就个人而言,我更喜欢尝试 - 除了一个,但它只是偏好。